🅕🅛🅐🅢🅚-🅓🅐🅝🅣🅘🅒
Flask-Dantic is a Python package that would enable users to use Pydantic models for validations and serialization, thus making it easy to link Flask with Pydantic.
It can validate the request params, query args and path args.
Also, the package provides a serializer that serializes the database objects using the pydantic models.
This comes handy if you are using pydantic models for request and response in Flask.
A single serialize call will take care of validating the returned response as well as serializing it. There are options to include or exclude certain fields or exclude/include fields with null values.
Compatibility
This package is compatible with Python >= 3.6
Installation
Install with pip:
pip install flask-dantic
Examples
Validating body parameters
from typing import Optional
from flask import current_app as flask_app, request
from pydantic import BaseModel
from flask_dantic import pydantic_validator
class UserCreateModel(BaseModel):
username: str
age: Optional[int] = None
phone: Optional[str] = None
@flask_app.route("/user/create", methods=["POST"])
@pydantic_validator(body=UserCreateModel)
def create_user():
"""
Request Json to create user that will be validated against UserModel
{
"username": "Foo",
"age": 42,
"phone": "123-456-7890"
}
"""
user_model = request.body_model
print(user_model.username, user_model.age, user_model.phone)
Change the default validation error status code. Default status code is 422
@flask_app.route("/user/create", methods=["POST"])
@pydantic_validator(body=UserCreateModel, validation_error_status_code=400)
def create_user():
"""
Request Json to create user that will be validated against UserModel
{
"username": "Foo",
"age": 42,
"phone": "123-456-7890"
}
"""
user_model = request.body_model
print(user_model.username, user_model.age, user_model.phone)
Validating Query args - request.args
from typing import Optional
from flask import current_app as flask_app, request
from pydantic import BaseModel
from flask_dantic import pydantic_validator
class UserQueryModel(BaseModel):
username: str
age: Optional[int] = None
@flask_app.route("/user/get", methods=["GET"])
@pydantic_validator(query=UserQueryModel)
def get_user():
user_query_model = request.query_model
print(user_query_model.username, user_query_model.age)
Validating URL Path args
from flask import current_app as flask_app, request
from pydantic import BaseModel, Field
from flask_dantic import pydantic_validator
UUID_REGEX = "[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}"
class UserPathParamModel(BaseModel):
user_id: str = Field(..., regex=UUID_REGEX, description="ID of the user")
@flask_app.route("/user/get/<string:user_id>", methods=["GET"])
@pydantic_validator(path_params=UserPathParamModel)
def get_user(user_id):
path_param_model = request.path_param_model
print(path_param_model.user_id)
Serialization using Pydantic module and returning the response.
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
db_engine = create_engine(DB_CONNECT_STRING)
db = Session(db_engine)
from http import HTTPStatus
from typing import Optional
from flask import current_app as flask_app, jsonify
from pydantic import BaseModel
from flask_dantic import serialize, pydantic_validator
class UserResponseModel(BaseModel):
username: str
age: Optional[int] = None
phone: Optional[str] = None
@flask_app.route("/user/list", methods=["GET"])
def get_all_users():
users = get_all_users_from_db()
serialized_users = serialize(users, UserResponseModel, many=True)
return jsonify(serialized_users), HTTPStatus.OK
@flask_app.route("/user/get/<string:user_id>", methods=["GET"])
@pydantic_validator(path_params=UserPathParamModel)
def get_user(user_id):
user = get_single_user_by_id(user_id)
user = serialize(user, UserResponseModel)
return jsonify(user), HTTPStatus.OK
Serialization - Dump directly to json. This is useful when you want to return the response as json without flask jsonify.
from flask_dantic import serialize
@flask_app.route("/user/get/<string:user_id>", methods=["GET"])
@pydantic_validator(path_params=UserPathParamModel)
def get_user(user_id):
user = get_single_user_by_id(user_id)
return serialize(user, UserResponseModel, json_dump=True), HTTPStatus.OK
Tests
Run tests:
pytest
License
Flask-Dantic is released under the MIT License. See the bundled LICENSE
file
for details.