Cornices / cornice

Build Web Services with Pyramid.
https://cornice.readthedocs.io
Other
384 stars 149 forks source link

Introspection and per-view schemas. #490

Open jenstroeger opened 6 years ago

jenstroeger commented 6 years ago

I’m trying to find a good way of handling request (and maybe response) schemas for the routes registered by the Cornice services.

Considering that every Service() registers an endpoint, and that decorated functions then supply the request validator and view implementation for that endpoint:

do_sth = Service(name='do_something', path='/__flush__')

@do_sth.post(
    schema=DoSthSchema(),  # ← This describes the expected request data, can I introspect on it?
    validator=(marshmallow_body_validator,),
    )
def do_sth_post(request):
    …

it would make sense to fetch the request schema for a view from right here. In fact, Cornice now supports Marshmallow schemas which can return a JSON Schema version for a data schema.

So my question: is there a good way to return the schema for a given view handler function, perhaps using Pyramid introspection? For example:

@schema_service.get(
    content_type="application/json",
    accept="application/json",
    )
def schema_get(request):
    """Return JSON Schema for the specified route’s validator."""

    route_name = request.matchdict["route_name"]
    for view in request.registry.introspector.get_category("views"):
        view_route_name = view["introspectable"]["route_name"]                                                           
        if route_name == view_route_name:
            # How do I get the GET, POST, … view function for the route?
            return …  # Get the view’s Marshmallow validator, then the validator’s JSON schema representation.
    return None  # Or return the JSON schemas for _all_ views.
jenstroeger commented 6 years ago

We ended up using the get_services() function, which returns a service object. Then use service.name and service.definitions, where the definitions contain the method, view, args = definition with arguments args to the view handlers of the service, and args["schema"] then is the Colander schema object.