Pyramid addon for OpenAPI3 validation
Project description
Validate Pyramid views against an OpenAPI 3.0 document
Peace of Mind
The reason this package exists is to give you peace of mind when providing a RESTful API. Instead of chasing down preventable bugs and saying sorry to consumers, you can focus on more important things in life.
- Your API documentation is never out-of-date, since it is generated out of the API document that you write.
- The documentation comes with try-it-out examples for every endpoint in your API. You don't have to provide (and maintain)
curl
commands to showcase how your API works. Users can try it themselves, right in their browsers. - Your API document is always valid, since your Pyramid app won't even start if the document is not according to OpenAPI 3.0 specification.
- Automatic request payload validation and sanitization. Your views do not require any code for validation and input sanitation. Your view code only deals with business logic. Tons of tests never need to be written since every request, and its payload, is validated against your API document before it reaches your view code.
- Your API responses always match your API document. Every response from your view is validated against your document and a
500 Internal Server Error
is returned if the response does not exactly match what your document says the output of a certain API endpoint should be. This decreases the effects of the Hyrum's Law. - A single source of truth. Because of the checks outlined above you can be sure that whatever your API document says is in fact what is going on in reality. You have a single source of truth to consult when asking an API related question, such as "Remind me again, which fields does the endpoint /user/info return?".
- Based on Pyramid, a mature Python Web framework. Companies such as Mozilla, Yelp, RollBar and SurveyMonkey trust Pyramid, and the new pypi.org runs on Pyramid too. Pyramid is thoroughly tested and documented, providing flexibility, performance, and a large ecosystem of high-quality add-ons.
Features
- Validates your API document (for example,
openapi.yaml
oropenapi.json
) against the OpenAPI 3.0 specification using the openapi-spec-validator. - Generates and serves the Swagger try-it-out documentation for your API.
- Validates incoming requests and outgoing responses against your API document using openapi-core.
Getting started
-
Declare
pyramid_openapi3
as a dependency in your Pyramid project. -
Include the following lines:
config.include("pyramid_openapi3")
config.pyramid_openapi3_spec('openapi.yaml', route='/api/v1/openapi.yaml')
config.pyramid_openapi3_add_explorer(route='/api/v1/')
- Use the
openapi
view predicate to enable request/response validation:
@view_config(route_name="foobar", openapi=True, renderer='json')
def myview(request):
return request.openapi_validated.parameters
For requests, request.openapi_validated
is available with two fields: parameters
and body
.
For responses, if the payload does not match the API document, an exception is raised.
Advanced configuration
Relative File References in Spec
A feature introduced in OpenApi3 is the ability to use $ref
links to external files (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#referenceObject).
In order to use this you must ensure that you have all of your spec files in a given directory (ensure that you do not have any code in this directory as all the files in it are exposed as static files), then replace the pyramid_openapi3_spec
call that you did in Getting Started with the following:
config.pyramid_openapi3_spec_directory('path/to/openapi.yaml', route='/api/v1/spec')
Some notes:
- Do not set the
route
of yourpyramid_openapi3_spec_directory
to the same value as theroute
ofpyramid_openapi3_add_explorer
. - The
route
that you set forpyramid_openapi3_spec_directory
should not contain any file extensions as this becomes the root for all of the files in your specifiedfilepath
. - You cannot use
pyramid_openapi3_spec_directory
andpyramid_openapi3_spec
in the same app.
Endpoints / Request / Response Validation
Provided with pyramid_openapi3
are a few validation features:
- incoming request validation (i.e. what a client sends to your app)
- outgoing response validation (i.e. what your app sends to a client)
- endpoint validation (i.e. your app registers routes for all defined API endpoints)
These features are enabled as a default, but you can disable them if you need to:
config.registry.settings["pyramid_openapi3.enable_endpoint_validation"] = False
config.registry.settings["pyramid_openapi3.enable_request_validation"] = False
config.registry.settings["pyramid_openapi3.enable_response_validation"] = False
Warning: Disabling request validation will result in
request.openapi_validated
no longer being available to use.
Demo / Examples
There are three examples provided with this package:
- A fairly simple single-file app providing a Hello World API.
- A slightly more built-out app providing a TODO app API.
- Another TODO app API, defined using a YAML spec split into multiple files.
Both examples come with tests that exhibit pyramid_openapi's error handling and validation capabilities.
A fully built-out app, with 100% test coverage, providing a RealWorld.io API is available at niteoweb/pyramid-realworld-example-app. It is a Heroku-deployable Pyramid app that provides an API for a Medium.com-like social app. You are encouraged to use it as a scaffold for your next project.
Design defense
The authors of pyramid_openapi3 believe that the approach of validating a manually-written API document is superior to the approach of generating the API document from Python code. Here are the reasons:
a) Both generation and validation against a document are lossy processes. The underlying libraries running the generation/validation will always have something missing. Either a feature from the latest OpenAPI specification, or an implementation bug. Having to fork the underlying library in order to generate the part of your API document that might only be needed for the frontend is unfortunate.
Validation on the other hand allows one to skip parts of validation that are not supported yet, and not block a team from shipping the document.
b) Validation approach does sacrifice DRY-ness, one has to write the API document and then the (view) code in Pyramid. Feels a bit redundant at first. However, this provides a clear separation between the intent and the implementation.
c) Generation approach has the drawback of having to write Python code even for parts of the API document that the Pyramid backend does not handle, as it might be handled by a different system, or be specific only to documentation or only to the client side of the API. This bloats your Pyramid codebase with code that does not belong there.
Running tests
You need to have pipenv and Python 3.7 or 3.8 installed on your machine. Then you can run:
$ make tests
Related packages
These packages tackle the same problem-space:
- pyramid_oas3 seems to do things very similarly to pyramid_openapi3, but the documentation is not in English and we sadly can't fully understand what it does just reading the code.
- pyramid_swagger does a similar thing, but for Swagger 2.0 documents.
- connexion takes the same "write spec first, code second" approach as pyramid_openapi3, but is based on Flask.
- bottle-swagger takes the same "write spec first, code second" approach too, but is based on Bottle.
- pyramid_apispec uses generation with help of apispec and marshmallow validation library. See above why we prefer validation instead of generation.
Deprecation policy
We do our best to follow the rules below.
- Support the latest two releases of Python, currently Python 3.7 and 3.8.
- Support only a single release of
openapi-core
and its sub-dependencies. SeePipfile.lock
for a frozen-in-time known-good-set of all dependencies.
Use in the wild
A couple of projects that use pyramid_openapi3 in production:
- WooCart API - User control panel for WooCart Managed WooCommerce service.
- Kafkai API - User control panel for Kafkai text generation service.
Changelog
0.10.2 (2020-10-27)
- Support for endpoint validation of prefixed routes. [zupo]
0.10.1 (2020-10-26)
- Support disabling of endpoint validation via INI files. [zupo]
0.10.0 (2020-10-26)
-
Allow relative file
$ref
links in OpenApi spec, refs #93. [damonhook] -
Validate that all endpoints in the spec have a registered route, refs #21. [phrfpeixoto]
0.9.0 (2020-08-16)
-
Add support for openapi-core 0.13.4. [sjiekak]
-
Add the ability to toggle request/response validation independently through registry settings. [damonhook]
0.8.3 (2020-06-21)
- Brown-bag release. [zupo]
0.8.2 (2020-06-21)
-
Raise a warning when a bad API spec causes validation errors to be discarded. [matthewwilkes]
-
Fix
custom_formatters
support in latest openapi-core 0.13.3. [simondale00] -
Declare a minimal supported version of openapi-core. [zupo]
0.8.1 (2020-05-03)
- Fix extract_errors to support lists, refs #75. [zupo]
0.8.0 (2020-04-20)
-
Log Response validation errors as errors, instead of warnings. [zupo]
-
Log Request validation errors as warnings, instead of infos. [zupo]
0.7.0 (2020-04-03)
-
Better support for handling apps mounted at subpaths. [mmerickel]
-
Pass the response into the response validation exception to support use-cases where we can return the response but log the errors. [mmerickel]
-
Reload development server also when YAML file changes. [mmerickel]
0.6.0 (2020-03-19)
- Better support for custom formatters and a test showcasing how to use them. [zupo]
0.5.2 (2020-03-16)
- Bad JWT tokens should result in 401 instead of 400. [zupo]
0.5.1 (2020-03-13)
- Fix a regression with relative
servers
entries inopenapi.yaml
. Refs https://github.com/p1c2u/openapi-core/issues/218. [zupo]
0.5.0 (2020-03-07)
-
[BREAKING CHANGE] Move
openapi_validation_error
fromexamples/todoapp
into the main package so it becomes a first-class citizen and people can use it without copy/pasting. If you need custom JSON rendering, you can provide your ownextract_errors
function viapyramid_openapi3_extract_errors
config setting. [zupo] -
Upgrade
openapi-core
to0.13.x
which brings a complete rewrite of the validation mechanism that is now based onjsonschema
library. This manifests as different validation error messages.[BREAKING CHANGE] By default,
openapi-core
no longer creates models from validated data, but returnsdict
s. More info on https://github.com/p1c2u/openapi-core/issues/205 [zupo]
0.4.1 (2019-10-22)
- Pin openapi-core dependency to a sub 0.12.0 version, to avoid regressions with validation. Details on https://github.com/p1c2u/openapi-core/issues/160 [zupo]
0.4.0 (2019-08-05)
-
Fix handling parameters in Headers and Cookies. [gweis]
-
Introduce RequestValidationError and ResponseValidationError exceptions in favor of pyramid_openapi3_validation_error_view directive. [gweis]
0.3.0 (2019-05-22)
- Added type hints. [zupo]
- Added additional references to other packages covering the same problem-space. [zupo]
- Moved repo to Pylons GitHub organization. [stevepiercy, zupo]
- Added a more built-out TODO-app example. [zupo]
0.2.8 (2019-04-17)
- Fix for double-registering views. [zupo]
- Added a single-file example. [zupo]
0.2.7 (2019-04-14)
- Tweaking the release process. [zupo]
0.2.6 (2019-04-14)
- Added a bunch of tests. [zupo]
0.2.5 (2019-04-08)
- Automatic releases via CircleCI. [zupo]
0.1.0 (2019-04-08)
- Initial release. [zupo]
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for pyramid_openapi3-0.10.2-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3144f555138561795fa115be35d2f9ea6c7e7feabe53f0962961e5818b2cc99c |
|
MD5 | ffa4fc703bb1288eb1abb1bfc3c7c71f |
|
BLAKE2b-256 | 2fb49b9443e236f39ce20c69d157ace5038201c8e35aac97f2a03a91c7a97058 |