From eafaec7962075808b249fc4c81e7335f646cbac6 Mon Sep 17 00:00:00 2001 From: Pavol Vargovcik Date: Thu, 20 Feb 2020 16:54:28 +0100 Subject: [PATCH 1/2] cache ConnexionRequest.json --- connexion/lifecycle.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/connexion/lifecycle.py b/connexion/lifecycle.py index 32fb0f26f..3f85ea94c 100644 --- a/connexion/lifecycle.py +++ b/connexion/lifecycle.py @@ -1,4 +1,3 @@ - class ConnexionRequest(object): def __init__(self, url, @@ -24,7 +23,9 @@ def __init__(self, @property def json(self): - return self.json_getter() + if not hasattr(self, '_json'): + self._json = self.json_getter() + return self._json class ConnexionResponse(object): From fd6174dff266094a315e035bd8cb174e2b1552bf Mon Sep 17 00:00:00 2001 From: Pavol Vargovcik Date: Thu, 20 Feb 2020 18:05:43 +0100 Subject: [PATCH 2/2] add openapi3 enforcedefaults_aiohttp example --- .../enforcedefaults_aiohttp/README.rst | 16 ++++++ .../enforcedefaults-api.yaml | 39 +++++++++++++ .../enforcedefaults.py | 56 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 examples/openapi3/enforcedefaults_aiohttp/README.rst create mode 100644 examples/openapi3/enforcedefaults_aiohttp/enforcedefaults-api.yaml create mode 100755 examples/openapi3/enforcedefaults_aiohttp/enforcedefaults.py diff --git a/examples/openapi3/enforcedefaults_aiohttp/README.rst b/examples/openapi3/enforcedefaults_aiohttp/README.rst new file mode 100644 index 000000000..906316116 --- /dev/null +++ b/examples/openapi3/enforcedefaults_aiohttp/README.rst @@ -0,0 +1,16 @@ +======================== +Custom Validator Example +======================== + +In this example we fill-in non-provided properties with their defaults. +Validator code is based on example from `python-jsonschema docs`_. + +Running: + +.. code-block:: bash + + $ ./enforcedefaults.py + +Now open your browser and go to http://localhost:8080/v1/ui/ to see the Swagger +UI. If you send a ``POST`` request with empty body ``{}``, you should receive +echo with defaults filled-in. diff --git a/examples/openapi3/enforcedefaults_aiohttp/enforcedefaults-api.yaml b/examples/openapi3/enforcedefaults_aiohttp/enforcedefaults-api.yaml new file mode 100644 index 000000000..02d00ebca --- /dev/null +++ b/examples/openapi3/enforcedefaults_aiohttp/enforcedefaults-api.yaml @@ -0,0 +1,39 @@ +openapi: '3.0.0' +info: + version: '1' + title: Custom Validator Example +servers: + - url: http://localhost:8080/{basePath} + variables: + basePath: + default: api +paths: + /echo: + post: + description: Echo passed data + operationId: enforcedefaults.echo + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Data' + responses: + '200': + description: Data with defaults filled in by validator + default: + description: Unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +components: + schemas: + Data: + type: object + properties: + foo: + type: string + default: foo + Error: + type: string diff --git a/examples/openapi3/enforcedefaults_aiohttp/enforcedefaults.py b/examples/openapi3/enforcedefaults_aiohttp/enforcedefaults.py new file mode 100755 index 000000000..cedfcc184 --- /dev/null +++ b/examples/openapi3/enforcedefaults_aiohttp/enforcedefaults.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +import connexion +import jsonschema +import six +from connexion.decorators.validation import RequestBodyValidator +from connexion.json_schema import Draft4RequestValidator + + +async def echo(body): + return body + + +# via https://python-jsonschema.readthedocs.io/ +def extend_with_set_default(validator_class): + validate_properties = validator_class.VALIDATORS['properties'] + + def set_defaults(validator, properties, instance, schema): + for property, subschema in six.iteritems(properties): + if 'default' in subschema: + instance.setdefault(property, subschema['default']) + + for error in validate_properties( + validator, properties, instance, schema): + yield error + + return jsonschema.validators.extend( + validator_class, {'properties': set_defaults}) + +DefaultsEnforcingDraft4Validator = extend_with_set_default(Draft4RequestValidator) + + +class DefaultsEnforcingRequestBodyValidator(RequestBodyValidator): + def __init__(self, *args, **kwargs): + super(DefaultsEnforcingRequestBodyValidator, self).__init__( + *args, validator=DefaultsEnforcingDraft4Validator, **kwargs) + + +validator_map = { + 'body': DefaultsEnforcingRequestBodyValidator +} + + +if __name__ == '__main__': + app = connexion.AioHttpApp( + __name__, + port=8080, + specification_dir='.', + options={'swagger_ui': True} + ) + app.add_api( + 'enforcedefaults-api.yaml', + arguments={'title': 'Hello World Example'}, + validator_map=validator_map, + ) + app.run()