Skip to main content

generate OpenAPI document and validate request & response with Python annotations.

Project description

Flask Pydantic Spec

A library to make it easy to add OpenAPI documentation to your Flask app, and validate the requests using Pydantic.

This library began as a fork of Spectree, but as we made changes we thought other people might be interested in our approach.

Features

  • Less boilerplate code, only annotations, no need for YAML :sparkles:
  • Generate API document with Redoc UI or Swagger UI :yum:
  • Validate query, JSON data, response data with pydantic :wink:
  • Has support for request/response types other than JSON.

Quick Start

install with pip: pip install flask-pydantic-spec

Examples

Check the examples folder.

Step by Step

  1. Define your data structure used in (query, json, headers, cookies, resp) with pydantic.BaseModel
  2. create flask_pydantic_spec.Validator instance with the web framework name you are using, like api = Validator('flask')
  3. api.validate decorate the route with
    • query
    • body
    • headers
    • cookies
    • resp
    • tags
  4. access this data with context(query, body, headers, cookies) (of course, you can access these from the original place where the framework offered)
    • flask: request.context
  5. register to the web application api.register(app)
  6. check the document at URL location /apidoc/redoc or /apidoc/swagger

If the request doesn't pass the validation, it will return a 422 with JSON error message(ctx, loc, msg, type).

How To

How to add summary and description to endpoints?

Just add docs to the endpoint function. The 1st line is the summary, and the rest is the description for this endpoint.

How to add description to parameters?

Check the pydantic docs about description in Field.

Any config I can change?

Of course. Check the config document.

You can update the config when you init the validator like:

from flask_pydantic_spec import FlaskPydanticSpec
FlaskPydanticSpec("flask", title="Demo API", version="v1.0", path="doc")

What is a Response and how to use it?

To build a response for the endpoint, you need to declare the status code with format HTTP_{code} and corresponding data (optional).

from flask_pydantic_spec import Response
Response(HTTP_200=None, HTTP_403=ForbidModel)
Response('HTTP_200') # equals to Response(HTTP_200=None)

What should I return when I'm using the library?

No need to change anything. Just return what the framework required.

How to logging when the validation failed?

Validation errors are logged with INFO level. Details are passed into extra.

How can I change the response when there is a validation error? Can I record some metrics?

This library provides before and after hooks to do these. Check the doc or the test case. You can change the handlers for Flask-Pydantic-Spec or for a specific endpoint validation.

Demo

Try it with http post :8000/api/user name=alice age=18. (if you are using httpie)

Flask

from flask import Flask, request, jsonify
from pydantic import BaseModel, Field, constr
from flask_pydantic_spec import FlaskPydanticSpec, Response, Request


class Profile(BaseModel):
    name: constr(min_length=2, max_length=40) # Constrained Str
    age: int = Field(
        ...,
        gt=0,
        lt=150,
        description='user age(Human)'
    )

    class Config:
        schema_extra = {
            # provide an example
            'example': {
                'name': 'very_important_user',
                'age': 42,
            }
        }


class Message(BaseModel):
    text: str


app = Flask(__name__)
api = FlaskPydanticSpec('flask')


@app.route('/api/user', methods=['POST'])
@api.validate(body=Request(Profile), resp=Response(HTTP_200=Message, HTTP_403=None), tags=['api'])
def user_profile():
    """
    verify user profile (summary of this endpoint)

    user's name, user's age, ... (long description)
    """
    print(request.context.json) # or `request.json`
    return jsonify(text='it works')


if __name__ == "__main__":
    api.register(app) # if you don't register in api init step
    app.run(port=8000)

FAQ

ValidationError: missing field for headers

The HTTP headers' keys in Flask are capitalized. You can use pydantic.root_validators(pre=True) to change all the keys into lower cases or upper cases.

ValidationError: value is not a valid list for query

Since there is no standard for HTTP query with multiple values, it's hard to find the way to handle this for different web frameworks. So I suggest not to use list type in query until I find a suitable way to fix it.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flask_pydantic_spec-0.3.1.tar.gz (20.8 kB view details)

Uploaded Source

Built Distribution

flask_pydantic_spec-0.3.1-py3-none-any.whl (20.7 kB view details)

Uploaded Python 3

File details

Details for the file flask_pydantic_spec-0.3.1.tar.gz.

File metadata

  • Download URL: flask_pydantic_spec-0.3.1.tar.gz
  • Upload date:
  • Size: 20.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/33.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.63.0 importlib-metadata/4.11.2 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.9.10

File hashes

Hashes for flask_pydantic_spec-0.3.1.tar.gz
Algorithm Hash digest
SHA256 a683460dadf6776ffc51324ab0922ff164190e5dfb1bb044ef3506e10a74ae85
MD5 85d30f9d9e4be4d4bf744b12d72df0e8
BLAKE2b-256 ccf83c65e65c4fb4ddee2411ca8050f6177bb3001dd6be36bee27bd130ebbe17

See more details on using hashes here.

File details

Details for the file flask_pydantic_spec-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: flask_pydantic_spec-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 20.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/33.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.63.0 importlib-metadata/4.11.2 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.9.10

File hashes

Hashes for flask_pydantic_spec-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4a096eff093e1f906611fef79c78b25fb50d873bb419510af7d81f812e728ae7
MD5 12ce80f54006fd28684627a4142e269f
BLAKE2b-256 c50eeec05347ea61338910d8f7530214f7e8f7413dbe1459d2c6e6db70d4396e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page