All Projects → bauerji → Flask_pydantic

bauerji / Flask_pydantic

Licence: mit
flask extension for integration with the awesome pydantic package

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Flask pydantic

Webargs
A friendly library for parsing HTTP request arguments, with built-in support for popular web frameworks, including Flask, Django, Bottle, Tornado, Pyramid, webapp2, Falcon, and aiohttp.
Stars: ✭ 1,145 (+1092.71%)
Mutual labels:  validation, flask
Marshmallow Jsonapi
JSON API 1.0 (https://jsonapi.org/) formatting with marshmallow
Stars: ✭ 203 (+111.46%)
Mutual labels:  validation, flask
Job Web Demo
Python Web 实战项目,Flask + Jinja2 + Bootstrap 开发的招聘网站
Stars: ✭ 87 (-9.37%)
Mutual labels:  flask
Markbj
一个开放的知识社区
Stars: ✭ 94 (-2.08%)
Mutual labels:  flask
Flaskdash
Flask starter app featuring CoreUI and the FlaskUser module.
Stars: ✭ 90 (-6.25%)
Mutual labels:  flask
Flask Paper Kit
Flask Boilerplate - Paper Kit Design | AppSeed
Stars: ✭ 89 (-7.29%)
Mutual labels:  flask
Watson Voice Bot
Create a Watson Assistant chatbot that uses voice over a web browser.
Stars: ✭ 92 (-4.17%)
Mutual labels:  flask
Pybooks
python books
Stars: ✭ 87 (-9.37%)
Mutual labels:  flask
Flask Rest Template
template for a rest app with flask, flask-rest and more...
Stars: ✭ 95 (-1.04%)
Mutual labels:  flask
Validator Collection
Python library of 60+ commonly-used validator functions
Stars: ✭ 91 (-5.21%)
Mutual labels:  validation
Validates timeliness
Date and time validation plugin for ActiveModel and Rails. Supports multiple ORMs and allows custom date/time formats.
Stars: ✭ 1,319 (+1273.96%)
Mutual labels:  validation
Solarpi
A RaspberryPi based, Flask powered photovoltaic monitor
Stars: ✭ 90 (-6.25%)
Mutual labels:  flask
Fluidvalidator
General purpose validation system for objects, nested objects, enumerables written in Swift
Stars: ✭ 89 (-7.29%)
Mutual labels:  validation
Work At Olist
Apply for a job at Olist's Development Team: https://bit.ly/olist-webdev
Stars: ✭ 93 (-3.12%)
Mutual labels:  flask
Monkeytail
Macro derived validation for cats.data.Validated
Stars: ✭ 87 (-9.37%)
Mutual labels:  validation
Gxgk Wechat Server
校园微信公众号,使用 Python、Flask、Redis、MySQL、Celery [DEPRECATED]
Stars: ✭ 1,325 (+1280.21%)
Mutual labels:  flask
Filetype
Fast, dependency-free, small Go package to infer the binary file type based on the magic numbers signature
Stars: ✭ 1,278 (+1231.25%)
Mutual labels:  validation
Incepiton Mysql
🍭A web platform designed for mysql inception
Stars: ✭ 90 (-6.25%)
Mutual labels:  flask
Flask Tutorial
这个项目已经很久很久了, 不推荐看, 不过倒是可以进群叨逼叨一下. 🚗 交流群:630398887
Stars: ✭ 91 (-5.21%)
Mutual labels:  flask
Covid 19 Nlp Vis
使用 flask + pyecharts 搭建的新冠肺炎疫情数据可视化交互分析网站平台,包含疫情数据获取、每日疫情地图、曲线图展示,数据统计分析、态势感知、确诊人数预测分析算法设计、NLP舆情监测等任务(数据更新到 6.19 )
Stars: ✭ 96 (+0%)
Mutual labels:  flask

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

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

  • 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: 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 3: 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
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].