Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support jsonschema decorator for injection into swagger gen / validation #1125

Open
kapilt opened this issue May 24, 2019 · 1 comment
Open

Comments

@kapilt
Copy link
Contributor

kapilt commented May 24, 2019

i've been using a simple decorator to get nicer ergonomics on view/route function signatures and type validation. I'd like to go ahead and add something like this to chalice, with the notion that it could also be used for swagger generation. Atm chalice swagger gen is effectively wild card method parameters with the empty object definition. Ideally with this decorator it would allow offloading request validation to api gateway, though i'm a bit unclear if thats supported by the underlying SAM transform although it looks like we could just inject a separate non sam request validator resource.

def schema(schema, required=None):
    """Decorator for chalice view functions to enable jsonschema                                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                                                                                                       
    At the moment it allows validation and keyword parameter                                                                                                                                                                                                                                                           
    passing based on extracted values.                                                                                                                                                                                                                                                                                 
    """
    # sugar syntax for skipping the declaration enclosure                                                                                                                                                                                                                                                                          
    if 'properties' not in schema:
        schema = {'properties': schema,
                  'type': 'object',
                  'additionalProperties': False}
    if '$schema' not in schema:
        schema['$schema'] = 'http://json-schema.org/schema#'
    if required and 'required' not in schema:
        schema['required'] = list(required)

    def wrapper(func):

        func.schema = schema

        @functools.wraps(func)
        def validate_invoke(*args, **kw):
            r = app.current_request
            if r.method == 'POST':
                rj = app.current_request.json_body
            elif r.method == 'GET':
                rj = app.current_request.query_params
            jsonschema.validate(rj, schema)
            kw = {}
            for k in schema['properties'].keys():
                if k in rj:
                    kw[k] = rj[k]
            return func(*args, **kw)

        return validate_invoke

    return wrapper

in terms of using it

@app.route('/create-foo', authorizer=authorizer, methods=['POST'])
@schema({'Duration': {'type': 'number'},
                  'Budget': {'type': 'number'}}, required=('Duration'))
def create_foo(Duration, Budget=0):
    # direct parameter extraction :-)
    return {}

Potentially this would allow for future extension to using python typing information.

tbd on referencing common model definitions across view functions.

@hjiawei
Copy link

hjiawei commented Aug 25, 2019

Very interesting. I have been doing similar validation in my functions but this proposal is much better than what I have.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants