flask extension for integration with the awesome pydantic package

Overview

Flask-Pydantic

Actions Status PyPI Language grade: Python License Code style

Flask extension for integration of the awesome pydantic package with Flask.

Installation

python3 -m pip install Flask-Pydantic

Basics

URL query and body parameters

validate decorator validates query and body request parameters and makes them accessible two ways:

  1. Using validate arguments, via flask's request variable
parameter type request attribute name
query query_params
body body_params
  1. Using the decorated function argument parameters type hints

URL path parameter

If you use annotated path URL path parameters as follows

@app.route("/users/", methods=["GET"])
@validate()
def get_user(user_id: str):
    pass

flask_pydantic will parse and validate user_id variable in the same manner as for body and query parameters.


Additional validate arguments

  • Success response status code can be modified via on_success_status parameter of validate decorator.
  • response_many parameter set to True enables serialization of multiple models (route function should therefore return iterable of models).
  • request_body_many parameter set to False analogically enables serialization of multiple models inside of the root level of request body. If the request body doesn't contain an array of objects 400 response is returned,
  • If validation fails, 400 response is returned with failure explanation.

For more details see in-code docstring or example app.

Usage

Example 1: Query parameters only

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 pydantic import BaseModel

from flask_pydantic import validate

app = Flask("flask_pydantic_app")

class QueryModel(BaseModel):
  age: int

class ResponseModel(BaseModel):
  id: int
  age: int
  name: str
  nickname: Optional[str]

# Example 1: query parameters only
@app.route("/", methods=["GET"])
@validate()
def get(query: QueryModel):
  age = query.age
  return ResponseModel(
    age=age,
    id=0, name="abc", nickname="123"
    )
See the full example app here
  • age query parameter is a required int
    • curl --location --request GET 'http://127.0.0.1:5000/'
    • 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)
    • curl --location --request GET 'http://127.0.0.1:5000/?age=abc'
      {
        "validation_error": {
          "query_params": [
            {
              "loc": ["age"],
              "msg": "value is not a valid integer",
              "type": "type_error.integer"
            }
          ]
        }
      }
  • likewise for body parameters
  • example call with valid parameters: curl --location --request GET 'http://127.0.0.1:5000/?age=20'

-> {"id": 0, "age": 20, "name": "abc", "nickname": "123"}

Example 2: URL path parameter

@app.route("/character//", methods=["GET"])
@validate()
def get_character(character_id: int):
    characters = [
        ResponseModel(id=1, age=95, name="Geralt", nickname="White Wolf"),
        ResponseModel(id=2, age=45, name="Triss Merigold", nickname="sorceress"),
        ResponseModel(id=3, age=42, name="Julian Alfred Pankratz", nickname="Jaskier"),
        ResponseModel(id=4, age=101, name="Yennefer", nickname="Yenn"),
    ]
    try:
        return characters[character_id]
    except IndexError:
        return {"error": "Not found"}, 400

Example 3: Request body only

class RequestBodyModel(BaseModel):
  name: str
  nickname: Optional[str]

# Example2: request body only
@app.route("/", methods=["POST"])
@validate()
def post(body: RequestBodyModel): 
  name = body.name
  nickname = body.nickname
  return ResponseModel(
    name=name, nickname=nickname,id=0, age=1000
    )
See the full example app here

Example 4: BOTH query paramaters and request body

# Example 3: both query paramters and request body
@app.route("/both", methods=["POST"])
@validate()
def get_and_post(body: RequestBodyModel,query: QueryModel):
  name = body.name # From request body
  nickname = body.nickname # From request body
  age = query.age # from query parameters
  return ResponseModel(
    age=age, name=name, nickname=nickname,
    id=0
  )
See the full example app here

Modify response status code

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():
    ...

Status code in case of validation error can be modified using FLASK_PYDANTIC_VALIDATION_ERROR_STATUS_CODE flask configuration variable.

Using the decorated function kwargs

Instead of passing body and query to validate, it is possible to directly defined them by using type hinting in the decorated function.

# necessary imports, app and models definition
...

@app.route("/", methods=["POST"])
@validate()
def post(body: BodyModel, query: QueryModel):
    return ResponseModel(
            id=id_,
            age=query.age,
            name=body.name,
            nickname=body.nickname,
        )

This way, the parsed data will be directly available in body and query. Furthermore, your IDE will be able to correctly type them.

Model aliases

Pydantic's alias feature is natively supported for query and body models. To use aliases in response modify response model

def modify_key(text: str) -> str:
    # do whatever you want with model keys
    return text


class MyModel(BaseModel):
    ...
    class Config:
        alias_generator = modify_key
        allow_population_by_field_name = True

and set response_by_alias=True in validate decorator

@app.route(...)
@validate(response_by_alias=True)
def my_route():
    ...
    return MyModel(...)

Example app

For more complete examples see example application.

Configuration

The behaviour can be configured using flask's application config FLASK_PYDANTIC_VALIDATION_ERROR_STATUS_CODE - response status code after validation error (defaults to 400)

Contributing

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

TODOs:

  • header request parameters
  • cookie request parameters
Stac-fastapi built on Tile38 and Redis to support caching

stac-fastapi-caching Stac-fastapi built on Tile38 to support caching. This code is built on top of stac-fastapi-elasticsearch 0.1.0 with pyle38, a Pyt

Jonathan Healy 4 Apr 11, 2022
Opinionated set of utilities on top of FastAPI

FastAPI Contrib Opinionated set of utilities on top of FastAPI Free software: MIT license Documentation: https://fastapi-contrib.readthedocs.io. Featu

identix.one 543 Jan 05, 2023
Lightning FastAPI

Lightning FastAPI Lightning FastAPI framework, provides boiler plates for FastAPI based on Django Framework Explaination / | │ manage.py │ README.

Rajesh Joshi 1 Oct 15, 2021
A fast and durable Pub/Sub channel over Websockets. FastAPI + WebSockets + PubSub == ⚡ 💪 ❤️

⚡ 🗞️ FastAPI Websocket Pub/Sub A fast and durable Pub/Sub channel over Websockets. The easiest way to create a live publish / subscribe multi-cast ov

8 Dec 06, 2022
CLI and Streamlit applications to create APIs from Excel data files within seconds, using FastAPI

FastAPI-Wrapper CLI & APIness Streamlit App Arvindra Sehmi, Oxford Economics Ltd. | Website | LinkedIn (Updated: 21 April, 2021) fastapi-wrapper is mo

Arvindra 49 Dec 03, 2022
Cookiecutter template for FastAPI projects using: Machine Learning, Poetry, Azure Pipelines and Pytests

cookiecutter-fastapi In order to create a template to FastAPI projects. 🚀 Important To use this project you don't need fork it. Just run cookiecutter

Arthur Henrique 225 Dec 28, 2022
API Simples com python utilizando a biblioteca FastApi

api-fastapi-python API Simples com python utilizando a biblioteca FastApi Para rodar esse script são necessárias duas bibliotecas: Fastapi: Comando de

Leonardo Grava 0 Apr 29, 2022
Minecraft biome tile server writing on Python using FastAPI

Blocktile Minecraft biome tile server writing on Python using FastAPI Usage https://blocktile.herokuapp.com/overworld/{seed}/{zoom}/{col}/{row}.png s

Vladimir 2 Aug 31, 2022
Пример использования GraphQL Ariadne с FastAPI и сравнение его с GraphQL Graphene FastAPI

FastAPI Ariadne Example Пример использования GraphQL Ariadne с FastAPI и сравнение его с GraphQL Graphene FastAPI - GitHub ###Запуск на локальном окру

ZeBrains Team 9 Nov 10, 2022
A minimal Streamlit app showing how to launch and stop a FastAPI process on demand

Simple Streamlit + FastAPI Integration A minimal Streamlit app showing how to launch and stop a FastAPI process on demand. The FastAPI /run route simu

Arvindra 18 Jan 02, 2023
Regex Converter for Flask URL Routes

Flask-Reggie Enable Regex Routes within Flask Installation pip install flask-reggie Configuration To enable regex routes within your application from

Rhys Elsmore 48 Mar 07, 2022
FastAPI + Postgres + Docker Compose + Heroku Deploy Template

FastAPI + Postgres + Docker Compose + Heroku Deploy ⚠️ For educational purpose only. Not ready for production use YET Features FastAPI with Postgres s

DP 12 Dec 27, 2022
API for Submarino store

submarino-api API for the submarino e-commerce documentation read the documentation in: https://submarino-api.herokuapp.com/docs or in https://submari

Miguel 1 Oct 14, 2021
Cube-CRUD is a simple example of a REST API CRUD in a context of rubik's cube review service.

Cube-CRUD is a simple example of a REST API CRUD in a context of rubik's cube review service. It uses Sqlalchemy ORM to manage the connection and database operations.

Sebastian Andrade 1 Dec 11, 2021
Browse JSON API in a HTML interface.

Falcon API Browse This project provides a middleware for Falcon Web Framework that will render the response in an HTML form for documentation purpose.

Abhilash Raj 4 Mar 16, 2022
Socket.IO integration for Flask applications.

Flask-SocketIO Socket.IO integration for Flask applications. Installation You can install this package as usual with pip: pip install flask-socketio

Miguel Grinberg 4.9k Jan 03, 2023
Middleware for Starlette that allows you to store and access the context data of a request. Can be used with logging so logs automatically use request headers such as x-request-id or x-correlation-id.

starlette context Middleware for Starlette that allows you to store and access the context data of a request. Can be used with logging so logs automat

Tomasz Wójcik 300 Dec 26, 2022
Fetching Cryptocurrency Prices from Coingecko and Displaying them on Grafana

cryptocurrency-prices-grafana Fetching Cryptocurrency Prices from Coingecko and Displaying them on Grafana About This stack consists of: Prometheus (t

Ruan Bekker 7 Aug 01, 2022
FastAPI Project Template

The base to start an openapi project featuring: SQLModel, Typer, FastAPI, JWT Token Auth, Interactive Shell, Management Commands.

A.Freud 4 Dec 05, 2022
Dead simple CSRF security middleware for Starlette ⭐ and Fast API ⚡

csrf-starlette-fastapi Dead simple CSRF security middleware for Starlette ⭐ and Fast API ⚡ Will work with either a input type="hidden" field or ajax

Nathaniel Sabanski 9 Nov 20, 2022