From 32720ce0a846922973371d97ea7adc16e1d9878f Mon Sep 17 00:00:00 2001 From: p1c2u Date: Wed, 22 Nov 2023 22:28:42 +0000 Subject: [PATCH] Docs integrations restructure --- docs/api.rst | 5 + docs/conf.py | 1 + docs/index.rst | 9 +- docs/integrations.rst | 512 -------------------------------- docs/integrations/aiohttp.rst | 29 ++ docs/integrations/bottle.rst | 4 + docs/integrations/django.rst | 82 +++++ docs/integrations/falcon.rst | 96 ++++++ docs/integrations/flask.rst | 129 ++++++++ docs/integrations/index.rst | 18 ++ docs/integrations/pyramid.rst | 4 + docs/integrations/requests.rst | 38 +++ docs/integrations/starlette.rst | 78 +++++ docs/integrations/tornado.rst | 4 + docs/integrations/werkzeug.rst | 33 ++ 15 files changed, 526 insertions(+), 516 deletions(-) create mode 100644 docs/api.rst delete mode 100644 docs/integrations.rst create mode 100644 docs/integrations/aiohttp.rst create mode 100644 docs/integrations/bottle.rst create mode 100644 docs/integrations/django.rst create mode 100644 docs/integrations/falcon.rst create mode 100644 docs/integrations/flask.rst create mode 100644 docs/integrations/index.rst create mode 100644 docs/integrations/pyramid.rst create mode 100644 docs/integrations/requests.rst create mode 100644 docs/integrations/starlette.rst create mode 100644 docs/integrations/tornado.rst create mode 100644 docs/integrations/werkzeug.rst diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 00000000..b8bc4955 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,5 @@ +API +=== + +.. autosummary:: + :toctree: generated diff --git a/docs/conf.py b/docs/conf.py index fa31b112..959c1bf8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -33,6 +33,7 @@ # ones. extensions = [ "sphinx.ext.autodoc", + 'sphinx.ext.autosummary', "sphinx.ext.doctest", "sphinx.ext.intersphinx", "sphinx.ext.coverage", diff --git a/docs/index.rst b/docs/index.rst index f2defc02..10f8c1f9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,15 +3,16 @@ openapi-core .. toctree:: :hidden: - :maxdepth: 2 + :maxdepth: 3 unmarshalling validation - integrations + integrations/index customizations security extensions contributing + api Openapi-core is a Python library that adds client-side and server-side support for the `OpenAPI v3.0 `__ @@ -21,7 +22,7 @@ Key features ------------ * :doc:`validation` and :doc:`unmarshalling ` of request and response data (including webhooks) -* :doc:`Integrations ` with popular libraries (Requests, Werkzeug) and frameworks (Django, Falcon, Flask, Starlette) +* :doc:`Integrations ` with popular libraries (Requests, Werkzeug) and frameworks (Django, Falcon, Flask, Starlette) * :doc:`Customization ` with **media type deserializers** and **format unmarshallers** * :doc:`Security ` data providers (API keys, Cookie, Basic and Bearer HTTP authentications) @@ -74,7 +75,7 @@ Retrieve validated and unmarshalled request data # get security data security = result.security -Request object should implement OpenAPI Request protocol. Check :doc:`integrations` to find oficially supported implementations. +Request object should implement OpenAPI Request protocol. Check :doc:`integrations/index` to find oficially supported implementations. For more details read about :doc:`unmarshalling` process. diff --git a/docs/integrations.rst b/docs/integrations.rst deleted file mode 100644 index c20247c1..00000000 --- a/docs/integrations.rst +++ /dev/null @@ -1,512 +0,0 @@ -Integrations -============ - -Openapi-core integrates with your popular libraries and frameworks. Each integration offers different levels of integration that help validate and unmarshal your request and response data. - -aiohttp.web ------------ - -This section describes integration with `aiohttp.web `__ framework. - -Low level -~~~~~~~~~ - -You can use ``AIOHTTPOpenAPIWebRequest`` as an aiohttp request factory: - -.. code-block:: python - - from openapi_core import unmarshal_request - from openapi_core.contrib.aiohttp import AIOHTTPOpenAPIWebRequest - - request_body = await aiohttp_request.text() - openapi_request = AIOHTTPOpenAPIWebRequest(aiohttp_request, body=request_body) - result = unmarshal_request(openapi_request, spec=spec) - -You can use ``AIOHTTPOpenAPIWebRequest`` as an aiohttp response factory: - -.. code-block:: python - - from openapi_core import unmarshal_response - from openapi_core.contrib.starlette import AIOHTTPOpenAPIWebRequest - - openapi_response = StarletteOpenAPIResponse(aiohttp_response) - result = unmarshal_response(openapi_request, openapi_response, spec=spec) - - -Bottle ------- - -See `bottle-openapi-3 `_ project. - - -Django ------- - -This section describes integration with `Django `__ web framework. -The integration supports Django from version 3.0 and above. - -Middleware -~~~~~~~~~~ - -Django can be integrated by middleware. Add ``DjangoOpenAPIMiddleware`` to your ``MIDDLEWARE`` list and define ``OPENAPI``. - -.. code-block:: python - :emphasize-lines: 6,9 - - # settings.py - from openapi_core import OpenAPI - - MIDDLEWARE = [ - # ... - 'openapi_core.contrib.django.middlewares.DjangoOpenAPIMiddleware', - ] - - OPENAPI = OpenAPI.from_dict(spec_dict) - -You can skip response validation process: by setting ``OPENAPI_RESPONSE_CLS`` to ``None`` - -.. code-block:: python - :emphasize-lines: 10 - - # settings.py - from openapi_core import OpenAPI - - MIDDLEWARE = [ - # ... - 'openapi_core.contrib.django.middlewares.DjangoOpenAPIMiddleware', - ] - - OPENAPI = OpenAPI.from_dict(spec_dict) - OPENAPI_RESPONSE_CLS = None - -After that you have access to unmarshal result object with all validated request data from Django view through request object. - -.. code-block:: python - - from django.views import View - - class MyView(View): - def get(self, req): - # get parameters object with path, query, cookies and headers parameters - validated_params = req.openapi.parameters - # or specific location parameters - validated_path_params = req.openapi.parameters.path - - # get body - validated_body = req.openapi.body - - # get security data - validated_security = req.openapi.security - -Low level -~~~~~~~~~ - -You can use ``DjangoOpenAPIRequest`` as a Django request factory: - -.. code-block:: python - - from openapi_core import unmarshal_request - from openapi_core.contrib.django import DjangoOpenAPIRequest - - openapi_request = DjangoOpenAPIRequest(django_request) - result = unmarshal_request(openapi_request, spec=spec) - -You can use ``DjangoOpenAPIResponse`` as a Django response factory: - -.. code-block:: python - - from openapi_core import unmarshal_response - from openapi_core.contrib.django import DjangoOpenAPIResponse - - openapi_response = DjangoOpenAPIResponse(django_response) - result = unmarshal_response(openapi_request, openapi_response, spec=spec) - - -Falcon ------- - -This section describes integration with `Falcon `__ web framework. -The integration supports Falcon from version 3.0 and above. - -Middleware -~~~~~~~~~~ - -The Falcon API can be integrated by ``FalconOpenAPIMiddleware`` middleware. - -.. code-block:: python - :emphasize-lines: 1,3,7 - - from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware - - openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec) - - app = falcon.App( - # ... - middleware=[openapi_middleware], - ) - -Additional customization parameters can be passed to the middleware. - -.. code-block:: python - :emphasize-lines: 5 - - from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware - - openapi_middleware = FalconOpenAPIMiddleware.from_spec( - spec, - extra_format_validators=extra_format_validators, - ) - - app = falcon.App( - # ... - middleware=[openapi_middleware], - ) - -You can skip response validation process: by setting ``response_cls`` to ``None`` - -.. code-block:: python - :emphasize-lines: 5 - - from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware - - openapi_middleware = FalconOpenAPIMiddleware.from_spec( - spec, - response_cls=None, - ) - - app = falcon.App( - # ... - middleware=[openapi_middleware], - ) - -After that you will have access to validation result object with all validated request data from Falcon view through request context. - -.. code-block:: python - - class ThingsResource: - def on_get(self, req, resp): - # get parameters object with path, query, cookies and headers parameters - validated_params = req.context.openapi.parameters - # or specific location parameters - validated_path_params = req.context.openapi.parameters.path - - # get body - validated_body = req.context.openapi.body - - # get security data - validated_security = req.context.openapi.security - -Low level -~~~~~~~~~ - -You can use ``FalconOpenAPIRequest`` as a Falcon request factory: - -.. code-block:: python - - from openapi_core import unmarshal_request - from openapi_core.contrib.falcon import FalconOpenAPIRequest - - openapi_request = FalconOpenAPIRequest(falcon_request) - result = unmarshal_request(openapi_request, spec=spec) - -You can use ``FalconOpenAPIResponse`` as a Falcon response factory: - -.. code-block:: python - - from openapi_core import unmarshal_response - from openapi_core.contrib.falcon import FalconOpenAPIResponse - - openapi_response = FalconOpenAPIResponse(falcon_response) - result = unmarshal_response(openapi_request, openapi_response, spec=spec) - - -Flask ------ - -This section describes integration with `Flask `__ web framework. - -Decorator -~~~~~~~~~ - -Flask views can be integrated by ``FlaskOpenAPIViewDecorator`` decorator. - -.. code-block:: python - :emphasize-lines: 1,3,6 - - from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator - - openapi = FlaskOpenAPIViewDecorator.from_spec(spec) - - @app.route('/home') - @openapi - def home(): - return "Welcome home" - -Additional customization parameters can be passed to the decorator. - -.. code-block:: python - :emphasize-lines: 5 - - from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator - - openapi = FlaskOpenAPIViewDecorator.from_spec( - spec, - extra_format_validators=extra_format_validators, - ) - -You can skip response validation process: by setting ``response_cls`` to ``None`` - -.. code-block:: python - :emphasize-lines: 5 - - from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator - - openapi = FlaskOpenAPIViewDecorator.from_spec( - spec, - response_cls=None, - ) - -If you want to decorate class based view you can use the decorators attribute: - -.. code-block:: python - :emphasize-lines: 2 - - class MyView(View): - decorators = [openapi] - - def dispatch_request(self): - return "Welcome home" - - app.add_url_rule('/home', view_func=MyView.as_view('home')) - -View -~~~~ - -As an alternative to the decorator-based integration, a Flask method based views can be integrated by inheritance from ``FlaskOpenAPIView`` class. - -.. code-block:: python - :emphasize-lines: 1,3,8 - - from openapi_core.contrib.flask.views import FlaskOpenAPIView - - class MyView(FlaskOpenAPIView): - def get(self): - return "Welcome home" - - app.add_url_rule( - '/home', - view_func=MyView.as_view('home', spec), - ) - -Additional customization parameters can be passed to the view. - -.. code-block:: python - :emphasize-lines: 10 - - from openapi_core.contrib.flask.views import FlaskOpenAPIView - - class MyView(FlaskOpenAPIView): - def get(self): - return "Welcome home" - - app.add_url_rule( - '/home', - view_func=MyView.as_view( - 'home', spec, - extra_format_validators=extra_format_validators, - ), - ) - -Request parameters -~~~~~~~~~~~~~~~~~~ - -In Flask, all unmarshalled request data are provided as Flask request object's ``openapi.parameters`` attribute - -.. code-block:: python - :emphasize-lines: 6,7 - - from flask.globals import request - - @app.route('/browse//') - @openapi - def browse(id): - browse_id = request.openapi.parameters.path['id'] - page = request.openapi.parameters.query.get('page', 1) - - return f"Browse {browse_id}, page {page}" - -Low level -~~~~~~~~~ - -You can use ``FlaskOpenAPIRequest`` as a Flask request factory: - -.. code-block:: python - - from openapi_core import unmarshal_request - from openapi_core.contrib.flask import FlaskOpenAPIRequest - - openapi_request = FlaskOpenAPIRequest(flask_request) - result = unmarshal_request(openapi_request, spec=spec) - -For response factory see `Werkzeug`_ integration. - - -Pyramid -------- - -See `pyramid_openapi3 `_ project. - - -Requests --------- - -This section describes integration with `Requests `__ library. - -Low level -~~~~~~~~~ - -You can use ``RequestsOpenAPIRequest`` as a Requests request factory: - -.. code-block:: python - - from openapi_core import unmarshal_request - from openapi_core.contrib.requests import RequestsOpenAPIRequest - - openapi_request = RequestsOpenAPIRequest(requests_request) - result = unmarshal_request(openapi_request, spec=spec) - -You can use ``RequestsOpenAPIResponse`` as a Requests response factory: - -.. code-block:: python - - from openapi_core import unmarshal_response - from openapi_core.contrib.requests import RequestsOpenAPIResponse - - openapi_response = RequestsOpenAPIResponse(requests_response) - result = unmarshal_response(openapi_request, openapi_response, spec=spec) - - -You can use ``RequestsOpenAPIWebhookRequest`` as a Requests webhook request factory: - -.. code-block:: python - - from openapi_core import unmarshal_request - from openapi_core.contrib.requests import RequestsOpenAPIWebhookRequest - - openapi_webhook_request = RequestsOpenAPIWebhookRequest(requests_request, "my_webhook") - result = unmarshal_request(openapi_webhook_request, spec=spec) - - -Starlette ---------- - -This section describes integration with `Starlette `__ ASGI framework. - -Middleware -~~~~~~~~~~ - -Starlette can be integrated by middleware. Add ``StarletteOpenAPIMiddleware`` with ``spec`` to your ``middleware`` list. - -.. code-block:: python - :emphasize-lines: 1,6 - - from openapi_core.contrib.starlette.middlewares import StarletteOpenAPIMiddleware - from starlette.applications import Starlette - from starlette.middleware import Middleware - - middleware = [ - Middleware(StarletteOpenAPIMiddleware, spec=spec), - ] - - app = Starlette( - # ... - middleware=middleware, - ) - -After that you have access to unmarshal result object with all validated request data from endpoint through ``openapi`` key of request's scope directory. - -.. code-block:: python - - async def get_endpoint(req): - # get parameters object with path, query, cookies and headers parameters - validated_params = req.scope["openapi"].parameters - # or specific location parameters - validated_path_params = req.scope["openapi"].parameters.path - - # get body - validated_body = req.scope["openapi"].body - - # get security data - validated_security = req.scope["openapi"].security - -You can skip response validation process: by setting ``response_cls`` to ``None`` - -.. code-block:: python - :emphasize-lines: 2 - - middleware = [ - Middleware(StarletteOpenAPIMiddleware, spec=spec, response_cls=None), - ] - - app = Starlette( - # ... - middleware=middleware, - ) - -Low level -~~~~~~~~~ - -You can use ``StarletteOpenAPIRequest`` as a Starlette request factory: - -.. code-block:: python - - from openapi_core import unmarshal_request - from openapi_core.contrib.starlette import StarletteOpenAPIRequest - - openapi_request = StarletteOpenAPIRequest(starlette_request) - result = unmarshal_request(openapi_request, spec=spec) - -You can use ``StarletteOpenAPIResponse`` as a Starlette response factory: - -.. code-block:: python - - from openapi_core import unmarshal_response - from openapi_core.contrib.starlette import StarletteOpenAPIResponse - - openapi_response = StarletteOpenAPIResponse(starlette_response) - result = unmarshal_response(openapi_request, openapi_response, spec=spec) - - -Tornado -------- - -See `tornado-openapi3 `_ project. - - -Werkzeug --------- - -This section describes integration with `Werkzeug `__ a WSGI web application library. - -Low level -~~~~~~~~~ - -You can use ``WerkzeugOpenAPIRequest`` as a Werkzeug request factory: - -.. code-block:: python - - from openapi_core import unmarshal_request - from openapi_core.contrib.werkzeug import WerkzeugOpenAPIRequest - - openapi_request = WerkzeugOpenAPIRequest(werkzeug_request) - result = unmarshal_request(openapi_request, spec=spec) - -You can use ``WerkzeugOpenAPIResponse`` as a Werkzeug response factory: - -.. code-block:: python - - from openapi_core import unmarshal_response - from openapi_core.contrib.werkzeug import WerkzeugOpenAPIResponse - - openapi_response = WerkzeugOpenAPIResponse(werkzeug_response) - result = unmarshal_response(openapi_request, openapi_response, spec=spec) diff --git a/docs/integrations/aiohttp.rst b/docs/integrations/aiohttp.rst new file mode 100644 index 00000000..0c144cb1 --- /dev/null +++ b/docs/integrations/aiohttp.rst @@ -0,0 +1,29 @@ +aiohttp.web +=========== + +This section describes integration with `aiohttp.web `__ framework. + +Low level +--------- + +You can use ``AIOHTTPOpenAPIWebRequest`` as an aiohttp request factory: + +.. code-block:: python + + from openapi_core import unmarshal_request + from openapi_core.contrib.aiohttp import AIOHTTPOpenAPIWebRequest + + request_body = await aiohttp_request.text() + openapi_request = AIOHTTPOpenAPIWebRequest(aiohttp_request, body=request_body) + result = unmarshal_request(openapi_request, spec=spec) + +You can use ``AIOHTTPOpenAPIWebRequest`` as an aiohttp response factory: + +.. code-block:: python + + from openapi_core import unmarshal_response + from openapi_core.contrib.starlette import AIOHTTPOpenAPIWebRequest + + openapi_response = StarletteOpenAPIResponse(aiohttp_response) + result = unmarshal_response(openapi_request, openapi_response, spec=spec) + diff --git a/docs/integrations/bottle.rst b/docs/integrations/bottle.rst new file mode 100644 index 00000000..5dd7f737 --- /dev/null +++ b/docs/integrations/bottle.rst @@ -0,0 +1,4 @@ +Bottle +====== + +See `bottle-openapi-3 `_ project. diff --git a/docs/integrations/django.rst b/docs/integrations/django.rst new file mode 100644 index 00000000..584226ea --- /dev/null +++ b/docs/integrations/django.rst @@ -0,0 +1,82 @@ +Django +====== + +This section describes integration with `Django `__ web framework. +The integration supports Django from version 3.0 and above. + +Middleware +---------- + +Django can be integrated by middleware. Add ``DjangoOpenAPIMiddleware`` to your ``MIDDLEWARE`` list and define ``OPENAPI``. + +.. code-block:: python + :emphasize-lines: 6,9 + + # settings.py + from openapi_core import OpenAPI + + MIDDLEWARE = [ + # ... + 'openapi_core.contrib.django.middlewares.DjangoOpenAPIMiddleware', + ] + + OPENAPI = OpenAPI.from_dict(spec_dict) + +You can skip response validation process: by setting ``OPENAPI_RESPONSE_CLS`` to ``None`` + +.. code-block:: python + :emphasize-lines: 10 + + # settings.py + from openapi_core import OpenAPI + + MIDDLEWARE = [ + # ... + 'openapi_core.contrib.django.middlewares.DjangoOpenAPIMiddleware', + ] + + OPENAPI = OpenAPI.from_dict(spec_dict) + OPENAPI_RESPONSE_CLS = None + +After that you have access to unmarshal result object with all validated request data from Django view through request object. + +.. code-block:: python + + from django.views import View + + class MyView(View): + def get(self, req): + # get parameters object with path, query, cookies and headers parameters + validated_params = req.openapi.parameters + # or specific location parameters + validated_path_params = req.openapi.parameters.path + + # get body + validated_body = req.openapi.body + + # get security data + validated_security = req.openapi.security + +Low level +--------- + +You can use ``DjangoOpenAPIRequest`` as a Django request factory: + +.. code-block:: python + + from openapi_core import unmarshal_request + from openapi_core.contrib.django import DjangoOpenAPIRequest + + openapi_request = DjangoOpenAPIRequest(django_request) + result = unmarshal_request(openapi_request, spec=spec) + +You can use ``DjangoOpenAPIResponse`` as a Django response factory: + +.. code-block:: python + + from openapi_core import unmarshal_response + from openapi_core.contrib.django import DjangoOpenAPIResponse + + openapi_response = DjangoOpenAPIResponse(django_response) + result = unmarshal_response(openapi_request, openapi_response, spec=spec) + diff --git a/docs/integrations/falcon.rst b/docs/integrations/falcon.rst new file mode 100644 index 00000000..fd228689 --- /dev/null +++ b/docs/integrations/falcon.rst @@ -0,0 +1,96 @@ +Falcon +====== + +This section describes integration with `Falcon `__ web framework. +The integration supports Falcon from version 3.0 and above. + +Middleware +---------- + +The Falcon API can be integrated by ``FalconOpenAPIMiddleware`` middleware. + +.. code-block:: python + :emphasize-lines: 1,3,7 + + from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware + + openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec) + + app = falcon.App( + # ... + middleware=[openapi_middleware], + ) + +Additional customization parameters can be passed to the middleware. + +.. code-block:: python + :emphasize-lines: 5 + + from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware + + openapi_middleware = FalconOpenAPIMiddleware.from_spec( + spec, + extra_format_validators=extra_format_validators, + ) + + app = falcon.App( + # ... + middleware=[openapi_middleware], + ) + +You can skip response validation process: by setting ``response_cls`` to ``None`` + +.. code-block:: python + :emphasize-lines: 5 + + from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware + + openapi_middleware = FalconOpenAPIMiddleware.from_spec( + spec, + response_cls=None, + ) + + app = falcon.App( + # ... + middleware=[openapi_middleware], + ) + +After that you will have access to validation result object with all validated request data from Falcon view through request context. + +.. code-block:: python + + class ThingsResource: + def on_get(self, req, resp): + # get parameters object with path, query, cookies and headers parameters + validated_params = req.context.openapi.parameters + # or specific location parameters + validated_path_params = req.context.openapi.parameters.path + + # get body + validated_body = req.context.openapi.body + + # get security data + validated_security = req.context.openapi.security + +Low level +--------- + +You can use ``FalconOpenAPIRequest`` as a Falcon request factory: + +.. code-block:: python + + from openapi_core import unmarshal_request + from openapi_core.contrib.falcon import FalconOpenAPIRequest + + openapi_request = FalconOpenAPIRequest(falcon_request) + result = unmarshal_request(openapi_request, spec=spec) + +You can use ``FalconOpenAPIResponse`` as a Falcon response factory: + +.. code-block:: python + + from openapi_core import unmarshal_response + from openapi_core.contrib.falcon import FalconOpenAPIResponse + + openapi_response = FalconOpenAPIResponse(falcon_response) + result = unmarshal_response(openapi_request, openapi_response, spec=spec) diff --git a/docs/integrations/flask.rst b/docs/integrations/flask.rst new file mode 100644 index 00000000..fee3b92a --- /dev/null +++ b/docs/integrations/flask.rst @@ -0,0 +1,129 @@ +Flask +====== + +This section describes integration with `Flask `__ web framework. + +Decorator +--------- + +Flask views can be integrated by ``FlaskOpenAPIViewDecorator`` decorator. + +.. code-block:: python + :emphasize-lines: 1,3,6 + + from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator + + openapi = FlaskOpenAPIViewDecorator.from_spec(spec) + + @app.route('/home') + @openapi + def home(): + return "Welcome home" + +Additional customization parameters can be passed to the decorator. + +.. code-block:: python + :emphasize-lines: 5 + + from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator + + openapi = FlaskOpenAPIViewDecorator.from_spec( + spec, + extra_format_validators=extra_format_validators, + ) + +You can skip response validation process: by setting ``response_cls`` to ``None`` + +.. code-block:: python + :emphasize-lines: 5 + + from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator + + openapi = FlaskOpenAPIViewDecorator.from_spec( + spec, + response_cls=None, + ) + +If you want to decorate class based view you can use the decorators attribute: + +.. code-block:: python + :emphasize-lines: 2 + + class MyView(View): + decorators = [openapi] + + def dispatch_request(self): + return "Welcome home" + + app.add_url_rule('/home', view_func=MyView.as_view('home')) + +View +---- + +As an alternative to the decorator-based integration, a Flask method based views can be integrated by inheritance from ``FlaskOpenAPIView`` class. + +.. code-block:: python + :emphasize-lines: 1,3,8 + + from openapi_core.contrib.flask.views import FlaskOpenAPIView + + class MyView(FlaskOpenAPIView): + def get(self): + return "Welcome home" + + app.add_url_rule( + '/home', + view_func=MyView.as_view('home', spec), + ) + +Additional customization parameters can be passed to the view. + +.. code-block:: python + :emphasize-lines: 10 + + from openapi_core.contrib.flask.views import FlaskOpenAPIView + + class MyView(FlaskOpenAPIView): + def get(self): + return "Welcome home" + + app.add_url_rule( + '/home', + view_func=MyView.as_view( + 'home', spec, + extra_format_validators=extra_format_validators, + ), + ) + +Request parameters +------------------ + +In Flask, all unmarshalled request data are provided as Flask request object's ``openapi.parameters`` attribute + +.. code-block:: python + :emphasize-lines: 6,7 + + from flask.globals import request + + @app.route('/browse//') + @openapi + def browse(id): + browse_id = request.openapi.parameters.path['id'] + page = request.openapi.parameters.query.get('page', 1) + + return f"Browse {browse_id}, page {page}" + +Low level +--------- + +You can use ``FlaskOpenAPIRequest`` as a Flask request factory: + +.. code-block:: python + + from openapi_core import unmarshal_request + from openapi_core.contrib.flask import FlaskOpenAPIRequest + + openapi_request = FlaskOpenAPIRequest(flask_request) + result = unmarshal_request(openapi_request, spec=spec) + +For response factory see `Werkzeug `_ integration. diff --git a/docs/integrations/index.rst b/docs/integrations/index.rst new file mode 100644 index 00000000..cd046758 --- /dev/null +++ b/docs/integrations/index.rst @@ -0,0 +1,18 @@ +Integrations +============ + +Openapi-core integrates with your popular libraries and frameworks. Each integration offers different levels of integration that help validate and unmarshal your request and response data. + +.. toctree:: + :maxdepth: 1 + + aiohttp + bottle + django + falcon + flask + pyramid + requests + starlette + tornado + werkzeug diff --git a/docs/integrations/pyramid.rst b/docs/integrations/pyramid.rst new file mode 100644 index 00000000..6989c5ce --- /dev/null +++ b/docs/integrations/pyramid.rst @@ -0,0 +1,4 @@ +Pyramid +======= + +See `pyramid_openapi3 `_ project. diff --git a/docs/integrations/requests.rst b/docs/integrations/requests.rst new file mode 100644 index 00000000..ef1ba788 --- /dev/null +++ b/docs/integrations/requests.rst @@ -0,0 +1,38 @@ +Requests +======== + +This section describes integration with `Requests `__ library. + +Low level +--------- + +You can use ``RequestsOpenAPIRequest`` as a Requests request factory: + +.. code-block:: python + + from openapi_core import unmarshal_request + from openapi_core.contrib.requests import RequestsOpenAPIRequest + + openapi_request = RequestsOpenAPIRequest(requests_request) + result = unmarshal_request(openapi_request, spec=spec) + +You can use ``RequestsOpenAPIResponse`` as a Requests response factory: + +.. code-block:: python + + from openapi_core import unmarshal_response + from openapi_core.contrib.requests import RequestsOpenAPIResponse + + openapi_response = RequestsOpenAPIResponse(requests_response) + result = unmarshal_response(openapi_request, openapi_response, spec=spec) + + +You can use ``RequestsOpenAPIWebhookRequest`` as a Requests webhook request factory: + +.. code-block:: python + + from openapi_core import unmarshal_request + from openapi_core.contrib.requests import RequestsOpenAPIWebhookRequest + + openapi_webhook_request = RequestsOpenAPIWebhookRequest(requests_request, "my_webhook") + result = unmarshal_request(openapi_webhook_request, spec=spec) diff --git a/docs/integrations/starlette.rst b/docs/integrations/starlette.rst new file mode 100644 index 00000000..06fc8dff --- /dev/null +++ b/docs/integrations/starlette.rst @@ -0,0 +1,78 @@ +Starlette +========= + +This section describes integration with `Starlette `__ ASGI framework. + +Middleware +---------- + +Starlette can be integrated by middleware. Add ``StarletteOpenAPIMiddleware`` with ``spec`` to your ``middleware`` list. + +.. code-block:: python + :emphasize-lines: 1,6 + + from openapi_core.contrib.starlette.middlewares import StarletteOpenAPIMiddleware + from starlette.applications import Starlette + from starlette.middleware import Middleware + + middleware = [ + Middleware(StarletteOpenAPIMiddleware, spec=spec), + ] + + app = Starlette( + # ... + middleware=middleware, + ) + +After that you have access to unmarshal result object with all validated request data from endpoint through ``openapi`` key of request's scope directory. + +.. code-block:: python + + async def get_endpoint(req): + # get parameters object with path, query, cookies and headers parameters + validated_params = req.scope["openapi"].parameters + # or specific location parameters + validated_path_params = req.scope["openapi"].parameters.path + + # get body + validated_body = req.scope["openapi"].body + + # get security data + validated_security = req.scope["openapi"].security + +You can skip response validation process: by setting ``response_cls`` to ``None`` + +.. code-block:: python + :emphasize-lines: 2 + + middleware = [ + Middleware(StarletteOpenAPIMiddleware, spec=spec, response_cls=None), + ] + + app = Starlette( + # ... + middleware=middleware, + ) + +Low level +--------- + +You can use ``StarletteOpenAPIRequest`` as a Starlette request factory: + +.. code-block:: python + + from openapi_core import unmarshal_request + from openapi_core.contrib.starlette import StarletteOpenAPIRequest + + openapi_request = StarletteOpenAPIRequest(starlette_request) + result = unmarshal_request(openapi_request, spec=spec) + +You can use ``StarletteOpenAPIResponse`` as a Starlette response factory: + +.. code-block:: python + + from openapi_core import unmarshal_response + from openapi_core.contrib.starlette import StarletteOpenAPIResponse + + openapi_response = StarletteOpenAPIResponse(starlette_response) + result = unmarshal_response(openapi_request, openapi_response, spec=spec) diff --git a/docs/integrations/tornado.rst b/docs/integrations/tornado.rst new file mode 100644 index 00000000..59ace988 --- /dev/null +++ b/docs/integrations/tornado.rst @@ -0,0 +1,4 @@ +Tornado +======= + +See `tornado-openapi3 `_ project. diff --git a/docs/integrations/werkzeug.rst b/docs/integrations/werkzeug.rst new file mode 100644 index 00000000..8136ff81 --- /dev/null +++ b/docs/integrations/werkzeug.rst @@ -0,0 +1,33 @@ +Werkzeug +======== + +This section describes integration with `Werkzeug `__ a WSGI web application library. + +Low level +--------- + +The integration defines ``WerkzeugOpenAPIRequest`` and ``WerkzeugOpenAPIResponse`` classes that convert +Werkzeug requests and responses to OpenAPI ones. + +.. md-tab-set:: + + .. md-tab-item:: Request + + .. code-block:: python + + from openapi_core.contrib.werkzeug import WerkzeugOpenAPIRequest + + openapi_request = WerkzeugOpenAPIRequest(werkzeug_request) + + result = openapi.unmarshal_request(openapi_request) + + .. md-tab-item:: Response + + .. code-block:: python + + from openapi_core.contrib.werkzeug import WerkzeugOpenAPIRequest, WerkzeugOpenAPIResponse + + openapi_request = WerkzeugOpenAPIRequest(werkzeug_request) + openapi_response = WerkzeugOpenAPIResponse(werkzeug_response) + + result = openapi.unmarshal_response(openapi_request, openapi_response)