Flask extension for integration of the awesome pydantic package with Flask.
validate
decorator validates query and body request parameters and makes them accessible via flask's request
variable
parameter type | request attribute name |
---|---|
query | query_params |
body | body_params |
- Success response status code can be modified via
on_success_status
parameter ofvalidate
decorator. response_many
parameter set toTrue
enables serialization of multiple models (route function should therefore return iterable of models).request_body_many
parameter set toFalse
analogically enables serialization of multiple models inside of the root level of request body. If the request body doesn't contain an array of objects400
response is returned,- If validation fails,
400
response is returned with failure explanation.
For more details see in-code docstring or example app.
Simply use validate
decorator on route function.
❗ Be aware that @app.route
decorator must precede @validate
(i. e. @validate
must be closer to the function declaration).
from typing import Optional
from flask import Flask, request
from flask_pydantic import validate
from pydantic import BaseModel
app = Flask("flask_pydantic_app")
class QueryModel(BaseModel):
age: int
class BodyModel(BaseModel):
name: str
nickname: Optional[str]
class ResponseModel(BaseModel):
id: int
age: int
name: str
nickname: Optional[str]
@app.route("/", methods=["POST"])
@validate(body=BodyModel, query=QueryModel)
def post():
# save model to DB
id_ = ...
return ResponseModel(
id=id_,
age=request.query_params.age,
name=request.body_params.name,
nickname=request.body_params.nickname,
)
age
query parameter is a requiredint
- if none is provided the response contains:
{ "validation_error": { "query_params": [ { "loc": [ "age" ], "msg": "field required", "type": "value_error.missing" } ] } }
- for incompatible type (e. g. string
/?age=not_a_number
){ "validation_error": { "query_params": [ { "loc": [ "age" ], "msg": "value is not a valid integer", "type": "type_error.integer" } ] } }
- if none is provided the response contains:
- likewise for body parameters
- example call with valid parameters:
curl -XPOST http://localhost:5000/?age=20 --data '{"name": "John Doe"}' -H 'Content-Type: application/json'
-> {"id": 2, "age": 20, "name": "John Doe", "nickname": null}
The default success status code is 200
. It can be modified in two ways
- in return statement
# necessary imports, app and models definition
...
@app.route("/", methods=["POST"])
@validate(body=BodyModel, query=QueryModel)
def post():
return ResponseModel(
id=id_,
age=request.query_params.age,
name=request.body_params.name,
nickname=request.body_params.nickname,
), 201
- in
validate
decorator
@app.route("/", methods=["POST"])
@validate(body=BodyModel, query=QueryModel, on_success_status=201)
def post():
...
Feature requests and pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
- clone repository
git clone https://github.com/bauerji/flask_pydantic.git cd flask_pydantic
- create virtual environment and activate it
python3 -m venv venv source venv/bin/activate
- install development requirements
python3 -m pip install -r requirements/test.pip
- checkout new branch and make your desired changes (don't forget to update tests)
git checkout -b <your_branch_name>
- run tests
python3 -m pytest
- if tests fails on Black tests, make sure You have your code compliant with style of Black formatter
- push your changes and create a pull request to master branch
- header request parameters
- cookie request parameters