Skip to content

Basic documentation #293

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

Merged
merged 1 commit into from
Feb 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ reports-cleanup:

test-cleanup: test-cache-cleanup reports-cleanup

docs-html:
sphinx-build -b html docs docs/_build

docs-cleanup:
@rm -rf docs/_build

cleanup: dist-cleanup test-cleanup
319 changes: 20 additions & 299 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,24 @@ About
#####

Openapi-core is a Python library that adds client-side and server-side support
for the `OpenAPI Specification v3.0.0 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md>`__.
for the `OpenAPI Specification v3 <https://github.com/OAI/OpenAPI-Specification>`__.

Key features
************

* **Validation** of requests and responses
* Schema **casting** and **unmarshalling**
* Media type and parameters **deserialization**
* **Security** providers (API keys, Cookie, Basic and Bearer HTTP authentications)
* Custom **deserializers** and **formats**
* **Integration** with libraries and frameworks


Documentation
#############

Check documentation to see more details about the features. All documentation is in the "docs" directory and online at `openapi-core.readthedocs.io <https://openapi-core.readthedocs.io>`__


Installation
############
Expand Down Expand Up @@ -81,7 +98,7 @@ and unmarshal request data from validation result
# get security data
validated_security = result.security

Request object should be instance of OpenAPIRequest class (See `Integrations`_).
Request object should be instance of OpenAPIRequest class (See `Integrations <https://openapi-core.readthedocs.io/en/latest/integrations.html>`__).

Response
********
Expand Down Expand Up @@ -111,303 +128,7 @@ and unmarshal response data from validation result
# get data
validated_data = result.data

Response object should be instance of OpenAPIResponse class (See `Integrations`_).

Security
********

openapi-core supports security for authentication and authorization process. Security data for security schemas are accessible from `security` attribute of `RequestValidationResult` object.

For given security specification:

.. code-block:: yaml

security:
- BasicAuth: []
- ApiKeyAuth: []
components:
securitySchemes:
BasicAuth:
type: http
scheme: basic
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key

you can access your security data the following:

.. code-block:: python

result = validator.validate(request)

# get basic auth decoded credentials
result.security['BasicAuth']

# get api key
result.security['ApiKeyAuth']

Supported security types:

* http – for Basic and Bearer HTTP authentications schemes
* apiKey – for API keys and cookie authentication


Customizations
##############

Spec validation
***************

By default, spec dict is validated on spec creation time. Disabling the validation can improve the performance.

.. code-block:: python

from openapi_core import create_spec

spec = create_spec(spec_dict, validate_spec=False)

Deserializers
*************

Pass custom defined media type deserializers dictionary with supported mimetypes as a key to `RequestValidator` or `ResponseValidator` constructor:

.. code-block:: python

def protobuf_deserializer(message):
feature = route_guide_pb2.Feature()
feature.ParseFromString(message)
return feature

custom_media_type_deserializers = {
'application/protobuf': protobuf_deserializer,
}

validator = ResponseValidator(
spec, custom_media_type_deserializers=custom_media_type_deserializers)

result = validator.validate(request, response)

Formats
*******

OpenAPI defines a ``format`` keyword that hints at how a value should be interpreted, e.g. a ``string`` with the type ``date`` should conform to the RFC 3339 date format.

Openapi-core comes with a set of built-in formatters, but it's also possible to add support for custom formatters for `RequestValidator` and `ResponseValidator`.

Here's how you could add support for a ``usdate`` format that handles dates of the form MM/DD/YYYY:

.. code-block:: python

from datetime import datetime
import re

class USDateFormatter:
def validate(self, value) -> bool:
return bool(re.match(r"^\d{1,2}/\d{1,2}/\d{4}$", value))

def unmarshal(self, value):
return datetime.strptime(value, "%m/%d/%y").date


custom_formatters = {
'usdate': USDateFormatter(),
}

validator = ResponseValidator(spec, custom_formatters=custom_formatters)

result = validator.validate(request, response)

Integrations
############

Django
******

For Django 2.2 you can use DjangoOpenAPIRequest a Django request factory:

.. code-block:: python

from openapi_core.validation.request.validators import RequestValidator
from openapi_core.contrib.django import DjangoOpenAPIRequest

openapi_request = DjangoOpenAPIRequest(django_request)
validator = RequestValidator(spec)
result = validator.validate(openapi_request)

You can use DjangoOpenAPIResponse as a Django response factory:

.. code-block:: python

from openapi_core.validation.response.validators import ResponseValidator
from openapi_core.contrib.django import DjangoOpenAPIResponse

openapi_response = DjangoOpenAPIResponse(django_response)
validator = ResponseValidator(spec)
result = validator.validate(openapi_request, openapi_response)

Falcon
******

This section describes integration with `Falcon <https://falconframework.org>`__ web framework.

Middleware
==========

Falcon API can be integrated by `FalconOpenAPIMiddleware` middleware.

.. code-block:: python

from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware

openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec)
api = falcon.API(middleware=[openapi_middleware])

Low level
=========

For Falcon you can use FalconOpenAPIRequest a Falcon request factory:

.. code-block:: python

from openapi_core.validation.request.validators import RequestValidator
from openapi_core.contrib.falcon import FalconOpenAPIRequestFactory

openapi_request = FalconOpenAPIRequestFactory.create(falcon_request)
validator = RequestValidator(spec)
result = validator.validate(openapi_request)

You can use FalconOpenAPIResponse as a Falcon response factory:

.. code-block:: python

from openapi_core.validation.response.validators import ResponseValidator
from openapi_core.contrib.falcon import FalconOpenAPIResponseFactory

openapi_response = FalconOpenAPIResponseFactory.create(falcon_response)
validator = ResponseValidator(spec)
result = validator.validate(openapi_request, openapi_response)

Flask
*****

Decorator
=========

Flask views can be integrated by `FlaskOpenAPIViewDecorator` decorator.

.. code-block:: python

from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator

openapi = FlaskOpenAPIViewDecorator.from_spec(spec)

@app.route('/home')
@openapi
def home():
pass

If you want to decorate class based view you can use the decorators attribute:

.. code-block:: python

class MyView(View):
decorators = [openapi]

View
====

As an alternative to the decorator-based integration, Flask method based views can be integrated by inheritance from `FlaskOpenAPIView` class.

.. code-block:: python

from openapi_core.contrib.flask.views import FlaskOpenAPIView

class MyView(FlaskOpenAPIView):
pass

app.add_url_rule('/home', view_func=MyView.as_view('home', spec))

Request parameters
==================

In Flask, all unmarshalled request data are provided as Flask request object's openapi.parameters attribute

.. code-block:: python

from flask.globals import request

@app.route('/browse/<id>/')
@openapi
def home():
browse_id = request.openapi.parameters.path['id']
page = request.openapi.parameters.query.get('page', 1)

Low level
=========

You can use FlaskOpenAPIRequest a Flask/Werkzeug request factory:

.. code-block:: python

from openapi_core.validation.request.validators import RequestValidator
from openapi_core.contrib.flask import FlaskOpenAPIRequest

openapi_request = FlaskOpenAPIRequest(flask_request)
validator = RequestValidator(spec)
result = validator.validate(openapi_request)

You can use FlaskOpenAPIResponse as a Flask/Werkzeug response factory:

.. code-block:: python

from openapi_core.validation.response.validators import ResponseValidator
from openapi_core.contrib.flask import FlaskOpenAPIResponse

openapi_response = FlaskOpenAPIResponse(flask_response)
validator = ResponseValidator(spec)
result = validator.validate(openapi_request, openapi_response)

Pyramid
*******

See `pyramid_openapi3 <https://github.com/niteoweb/pyramid_openapi3>`_ project.

Bottle
*******

See `bottle-openapi-3 <https://github.com/cope-systems/bottle-openapi-3>`_ project.


Requests
********

This section describes integration with `Requests <https://requests.readthedocs.io>`__ library.

Low level
=========

For Requests you can use RequestsOpenAPIRequest a Requests request factory:

.. code-block:: python

from openapi_core.validation.request.validators import RequestValidator
from openapi_core.contrib.requests import RequestsOpenAPIRequest

openapi_request = RequestsOpenAPIRequest(requests_request)
validator = RequestValidator(spec)
result = validator.validate(openapi_request)

You can use RequestsOpenAPIResponse as a Requests response factory:

.. code-block:: python

from openapi_core.validation.response.validators import ResponseValidator
from openapi_core.contrib.requests import RequestsOpenAPIResponse

openapi_response = RequestsOpenAPIResponse(requests_response)
validator = ResponseValidator(spec)
result = validator.validate(openapi_request, openapi_response)
Response object should be instance of OpenAPIResponse class (See `Integrations <https://openapi-core.readthedocs.io/en/latest/integrations.html>`__).

Related projects
################
Expand Down
Loading