2019-10-19 23:39:13 +00:00
***** ***** **
2017-09-21 11:51:37 +00:00
openapi-core
***** ***** **
2017-09-21 12:36:15 +00:00
.. image :: https://img.shields.io/pypi/v/openapi-core.svg
:target: https://pypi.python.org/pypi/openapi-core
.. image :: https://travis-ci.org/p1c2u/openapi-core.svg?branch=master
:target: https://travis-ci.org/p1c2u/openapi-core
.. image :: https://img.shields.io/codecov/c/github/p1c2u/openapi-core/master.svg?style=flat
:target: https://codecov.io/github/p1c2u/openapi-core?branch=master
.. image :: https://img.shields.io/pypi/pyversions/openapi-core.svg
:target: https://pypi.python.org/pypi/openapi-core
.. image :: https://img.shields.io/pypi/format/openapi-core.svg
:target: https://pypi.python.org/pypi/openapi-core
.. image :: https://img.shields.io/pypi/status/openapi-core.svg
:target: https://pypi.python.org/pypi/openapi-core
About
2019-10-19 23:39:13 +00:00
#####
2017-09-21 12:36:15 +00:00
2017-09-21 11:51:37 +00:00
Openapi-core is a Python library that adds client-side and server-side support
2017-09-21 11:54:09 +00:00
for the `OpenAPI Specification v3.0.0 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md> `__ .
2017-09-21 11:51:37 +00:00
Installation
2019-10-19 23:39:13 +00:00
############
2017-09-21 11:51:37 +00:00
Recommended way (via pip):
::
$ pip install openapi-core
Alternatively you can download the code and install from the repository:
.. code-block :: bash
$ pip install -e git+https://github.com/p1c2u/openapi-core.git#egg=openapi_core
2017-09-22 09:15:27 +00:00
Usage
2019-10-19 23:39:13 +00:00
#####
2017-09-22 09:15:27 +00:00
Firstly create your specification:
.. code-block :: python
from openapi_core import create_spec
spec = create_spec(spec_dict)
2019-10-19 23:39:13 +00:00
Request
***** **
2017-11-03 14:49:57 +00:00
Now you can use it to validate requests
2017-09-22 09:15:27 +00:00
.. code-block :: python
2020-02-18 11:57:15 +00:00
from openapi_core.validation.request.validators import RequestValidator
2017-09-22 09:15:27 +00:00
2017-11-02 16:20:08 +00:00
validator = RequestValidator(spec)
result = validator.validate(request)
# raise errors if request invalid
2017-11-03 14:55:21 +00:00
result.raise_for_errors()
2017-11-02 16:20:08 +00:00
2017-11-03 14:49:57 +00:00
# get list of errors
errors = result.errors
and unmarshal request data from validation result
.. code-block :: python
2019-10-19 12:59:16 +00:00
# get parameters object with path, query, cookies and headers parameters
2017-11-03 14:49:57 +00:00
validated_params = result.parameters
2019-10-19 12:59:16 +00:00
# or specific parameters
validated_path_params = result.parameters.path
2017-11-02 16:20:08 +00:00
# get body
2017-11-03 14:49:57 +00:00
validated_body = result.body
2017-09-22 09:15:27 +00:00
2020-02-04 20:35:23 +00:00
# get security data
validated_security = result.security
2019-10-19 23:39:13 +00:00
Request object should be instance of OpenAPIRequest class (See `Integrations`_ ).
Response
***** ***
You can also validate responses
.. code-block :: python
2020-02-18 11:57:15 +00:00
from openapi_core.validation.response.validators import ResponseValidator
2019-10-19 23:39:13 +00:00
validator = ResponseValidator(spec)
result = validator.validate(request, response)
# raise errors if response invalid
result.raise_for_errors()
# get list of errors
errors = result.errors
and unmarshal response data from validation result
.. code-block :: python
# get headers
validated_headers = result.headers
# get data
validated_data = result.data
Response object should be instance of OpenAPIResponse class (See `Integrations`_ ).
2020-02-04 20:35:23 +00:00
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
2019-10-19 23:39:13 +00:00
2020-02-03 16:30:31 +00:00
Customizations
##############
2021-02-12 23:41:01 +00:00
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)
2020-02-03 16:30:31 +00:00
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)
2020-03-26 00:34:36 +00:00
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)
2020-02-03 16:30:31 +00:00
2019-10-19 23:39:13 +00:00
Integrations
############
Django
***** *
2019-10-20 02:00:10 +00:00
For Django 2.2 you can use DjangoOpenAPIRequest a Django request factory:
2017-11-03 14:22:23 +00:00
.. code-block :: python
2020-02-18 11:57:15 +00:00
from openapi_core.validation.request.validators import RequestValidator
2019-10-19 23:39:13 +00:00
from openapi_core.contrib.django import DjangoOpenAPIRequest
2017-11-03 14:22:23 +00:00
2019-10-19 23:39:13 +00:00
openapi_request = DjangoOpenAPIRequest(django_request)
2017-11-03 14:22:23 +00:00
validator = RequestValidator(spec)
result = validator.validate(openapi_request)
2019-10-19 23:39:13 +00:00
You can use DjangoOpenAPIResponse as a Django response factory:
2017-11-06 14:13:40 +00:00
.. code-block :: python
2020-02-18 11:57:15 +00:00
from openapi_core.validation.response.validators import ResponseValidator
2019-10-19 23:39:13 +00:00
from openapi_core.contrib.django import DjangoOpenAPIResponse
2017-11-06 14:13:40 +00:00
2019-10-19 23:39:13 +00:00
openapi_response = DjangoOpenAPIResponse(django_response)
2017-11-06 14:13:40 +00:00
validator = ResponseValidator(spec)
2019-10-19 23:39:13 +00:00
result = validator.validate(openapi_request, openapi_response)
2017-11-06 14:13:40 +00:00
2020-02-17 16:33:01 +00:00
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
2020-04-06 20:10:23 +00:00
from openapi_core.contrib.falcon import FalconOpenAPIRequestFactory
2020-02-17 16:33:01 +00:00
2020-04-06 20:10:23 +00:00
openapi_request = FalconOpenAPIRequestFactory.create(falcon_request)
2020-02-17 16:33:01 +00:00
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
2020-04-06 20:10:23 +00:00
from openapi_core.contrib.falcon import FalconOpenAPIResponseFactory
2020-02-17 16:33:01 +00:00
2020-04-06 20:10:23 +00:00
openapi_response = FalconOpenAPIResponseFactory.create(falcon_response)
2020-02-17 16:33:01 +00:00
validator = ResponseValidator(spec)
result = validator.validate(openapi_request, openapi_response)
2019-10-19 23:39:13 +00:00
Flask
*****
2020-01-26 23:29:41 +00:00
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))
2020-01-27 11:10:54 +00:00
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)
2020-01-26 23:29:41 +00:00
Low level
=========
2019-10-19 23:39:13 +00:00
You can use FlaskOpenAPIRequest a Flask/Werkzeug request factory:
2017-11-06 14:13:40 +00:00
.. code-block :: python
2020-02-18 11:57:15 +00:00
from openapi_core.validation.request.validators import RequestValidator
2019-10-19 23:39:13 +00:00
from openapi_core.contrib.flask import FlaskOpenAPIRequest
2017-11-06 14:13:40 +00:00
2019-10-19 23:39:13 +00:00
openapi_request = FlaskOpenAPIRequest(flask_request)
validator = RequestValidator(spec)
result = validator.validate(openapi_request)
2017-11-06 14:13:40 +00:00
2019-10-19 23:39:13 +00:00
You can use FlaskOpenAPIResponse as a Flask/Werkzeug response factory:
2017-11-06 14:32:46 +00:00
.. code-block :: python
2020-02-18 11:57:15 +00:00
from openapi_core.validation.response.validators import ResponseValidator
2019-10-19 11:01:50 +00:00
from openapi_core.contrib.flask import FlaskOpenAPIResponse
2017-11-06 14:32:46 +00:00
openapi_response = FlaskOpenAPIResponse(flask_response)
validator = ResponseValidator(spec)
result = validator.validate(openapi_request, openapi_response)
2019-10-19 23:39:13 +00:00
Pyramid
***** **
See `pyramid_openapi3 <https://github.com/niteoweb/pyramid_openapi3> `_ project.
2021-01-02 19:46:25 +00:00
Bottle
***** **
See `bottle-openapi-3 <https://github.com/cope-systems/bottle-openapi-3> `_ project.
2020-03-02 16:05:36 +00:00
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)
2017-09-21 11:51:37 +00:00
Related projects
2019-10-19 23:39:13 +00:00
################
2017-09-21 11:51:37 +00:00
* `openapi-spec-validator <https://github.com/p1c2u/openapi-spec-validator> `__
2020-03-05 11:28:21 +00:00
* `openapi-schema-validator <https://github.com/p1c2u/openapi-schema-validator> `__
2018-07-10 16:22:01 +00:00
* `pyramid_openapi3 <https://github.com/niteoweb/pyramid_openapi3> `__