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
Comments
  • Flask Get Request validate failed

    Flask Get Request validate failed

    from pydantic import BaseModel
    from typing import List
    class Query(BaseModel):
        query: str
        
    @test_bp.route("/test_route")
    @validate(query=Query)
    def test_route(query:Query):
        return {}
    

    my code is very simple, but when i send 'http://127.0.0.1:8800/test_route?query=1',I will receive

    {
      "validation_error": {
        "query_params": [
          {
            "loc": [
              "query"
            ], 
            "msg": "str type expected", 
            "type": "type_error.str"
          }
        ], 
      }
    }
    

    I try add more detail in core.py

    try:
                        q = query_model(**query_params)
                    except ValidationError as ve:
                        err["query_params"] = ve.errors()
                        err["value"] = query_params
    

    I will get

    "value": {
          "query": [
            "1"
          ]
        }
    

    So I'm very doubt why query becomes list rather than str.

    My python requrement is

    python3.6
    pydantic==1.7.3
    flask-pydantic-spec==0.1.3
    Flask==1.1.2
    dataclasses==0.8
    

    Looking forward to a reply!

    opened by CharmingZhou 10
  • match flask pattern to return extra headers

    match flask pattern to return extra headers

    Technically Flask allows you to return from a route with a tuple of 3 items with the last item being a dictionary of headers. The docs mention it here: https://flask.palletsprojects.com/en/1.1.x/quickstart/#about-responses This adjusts the behavior of the validate decorator to allow this as well. Matches the behavior in: https://github.com/pallets/flask/blob/64213fc0214c1044fa2c9e60d0e2683e75d125c0/src/flask/app.py#L1644-L1646

    opened by cardoe 9
  • Dealing with Query Param Arrays

    Dealing with Query Param Arrays

    Another question - how would I go about validating query param arrays?

    For example I have code like this:

    response = test_client.get("/api/v1/services", query_string={"ids[]": ["5f03539f9472e7f1a153797d"]})
    
    assert response.status_code == 200
    
    @services_bp.route("", methods=["GET"], strict_slashes=False)
    @validate(query=GetObjectIds)
    def get_services():
        """
        Retrieves list of all services
        """
        data = request.args.getlist("ids[]")
    
        if not data:
            services = service_db.all_services()
        else:
            services = service_db.get_services([x for x in data])
    
        if len(services) > 0:
            return jsonify([service.dict() for service in services])
        else:
            return jsonify(error="No services found with requested ids"), 404
    

    I'd like to be able to have a model that says "validate that the get query correctly contains an id of lists."

    opened by jhoover4 8
  • Model.json() vs jsonify

    Model.json() vs jsonify

    Hello,

    Thanks for the app! We were beginning to play around with it and wondering if the returned json could be wrapped in jsonify or if there is an advantage to not to. We have our jsonify set just right to play nice with Mongo, etc., so we wanted to make sure we didn't lose any of its advantages.

    Thanks!

    opened by jhoover4 5
  • allow custom error responses to be generated

    allow custom error responses to be generated

    By defining a new config value that flask_pydantic looks for (FLASK_PYDANTIC_VALIDATION_ERROR_RAISE), we can support raising an exception when we have a validation error. If that is set and the exception is raised, by default, Flask will respond with a 500 error. However, by coupling that feature with Flask.register_error_handler, the user can catch the thrown exception and return whatever custom error response the user wishes. Fixes https://github.com/bauerji/flask-pydantic/issues/45.

    opened by jcreekmore 4
  • Add kwargs parsing

    Add kwargs parsing

    This PR is implementing solution 2 of #12.

    @bauerji like I said in the issue I already implemented a solution, so this is the PR.

    I am, of course, still open to discuss the different solutions !

    opened by adriencaccia 4
  • Overriding http return stats on exception

    Overriding http return stats on exception

    I notice that you can update the returned status on success, but can you do the same thing on error? We typically use 422s instead of 400s for malformed requests.

    Thanks!

    opened by jhoover4 4
  • ignore return-type annotations

    ignore return-type annotations

    This fixes an issue where any function with return-type annotations will get processed through parse_obj_as, and inevitably throw a validation exception, which will be returned as a very confusing error message where the "loc" property is "return".

    opened by laanak08 3
  • Request change: the example in the main README.md file is not clear

    Request change: the example in the main README.md file is not clear

    Before I start, I really thank you so much for this package.


    I request to make a change: The example at the README.md file in the main page of the package is not clear. At first, I thought that the package was not working correctly. I kept working, and sending requests till finally worked after about 15 minutes of trying.


    For this reason: The example is very advanced, and for someone who wanna learn the package for the first time, the learning curve of the example is very hard to learn. This is dangerous for someone who wants to learn about the package for the first time.


    So I would like to solve this problem by doing this. Create 3 separate endpoints:

    1. To read the GET request only, and above it the pydantic class of it.
    2. To read the JSON request body only, and above it the pydantic class of it.
    3. To read both the JSON request and the GET request together, using the old pydantic classes.

    If God willed, I can make this change. I will make these changes, If you give the permission. Thank you!

    opened by OmarThinks 3
  • Validation for Array of Models fails

    Validation for Array of Models fails

    from typing import List
    from flask_pydantic import validate
    
    api = Blueprint("lineage-collector", __name__)
    
    class EntityPayload(BaseModel):
        attributes: dict
        typeName: str
    
    class EntityPayloadBulk(BaseModel):
        __root__:  List[EntityPayload]
    
    @api.route('/entity/bulk', methods=["POST"])
    @validate()
    def entity_bulk(body: EntityPayloadBulk):
        return "Hello World"
    
    

    Call to this endpoint returns the following error:

    ` File "/usr/local/lib/python3.9/site-packages/flask_pydantic/core.py", line 158, in wrapper b = body_model(**body_params) TypeError: api.routes.EntityPayloadBulk() argument after ** must be a mapping, not list

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last): File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2464, in call return self.wsgi_app(environ, start_response) File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2450, in wsgi_app response = self.handle_exception(e) File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1867, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/local/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise raise value File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2447, in wsgi_app response = self.full_dispatch_request() File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1952, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1821, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/local/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise raise value File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request return self.view_functionsrule.endpoint File "/usr/local/lib/python3.9/site-packages/flask_pydantic/core.py", line 164, in wrapper raise JsonBodyParsingError() flask_pydantic.exceptions.JsonBodyParsingError`

    opened by ckwojai 3
  • Is there a way to convert key casing in responses?

    Is there a way to convert key casing in responses?

    I'd like to have my Pydantic models defined in snake_case but have the API return JSON with camelCase fields.

    In FastAPI, I can do the following:

    def to_camel(string: str):
        # returns "string" converted to camelCase
    
    class MyModel(BaseModel):
        foo_bar: str
    
        class Config:
            alias_generator = to_camel
            allow_population_by_field_name = True
    

    And the resulting JSON will be {"fooBar": "x"}. This is similar to the way it's described in the Pydantic docs.

    This doesn't work with flask-pydantic. Is there any way to achieve similar behaviour?

    opened by eboddington 3
  • Aliased list query parameters do not work

    Aliased list query parameters do not work

    flask-pydantic==0.10.0
    flask==2.1.2
    

    Steps to reproduce

    1. Define a query model with an aliased list field.
    class QueryModel(BaseModel):
        order_by: Optional[
            List[Literal["created", "name"]]
        ] = Field(..., alias="order-by")
    
        class Config:
            allow_population_by_field_name = True
    
    1. Set this as query: QueryModel in your request handler function signature.
    2. Send a request with ?order-by=name

    Expected result

    • The request should be considered valid.
    • query.order_by should be a list ['name'].

    Actual result

    {
      "validation_error": {
        "query_params": [
          {
            "loc": [
              "order-by"
            ], 
            "msg": "value is not a valid list", 
            "type": "type_error.list"
          }
        ]
      }
    }
    

    In short:

    • Aliased query params work.
    • List query params work (e.g. ?order_by=name&order_by=created gives you list with these values).
    • Aliased list query params do not work.
    opened by janibonnevier 0
  • Why doesn't the `make_json_response` function have a default value for the `by_alias` argument?

    Why doesn't the `make_json_response` function have a default value for the `by_alias` argument?

    def make_json_response(
        content: Union[BaseModel, Iterable[BaseModel]],
        status_code: int,
        by_alias: bool,
        exclude_none: bool = False,
        many: bool = False,
    ) -> Response:
        ...
            js = content.json(exclude_none=exclude_none, by_alias=by_alias)
        ...
    

    The content.json method has a default value for the by_alias argument.

    opened by NiKuma0 0
  • Error if validation error contains enum.Enum

    Error if validation error contains enum.Enum

    This error is occurring for me when the body of an endpoint receives a pydantic.BaseModel that contains a field of type Enum and the validation fail, the error message returned is a JSON serialization error instead of a ValidationError.

    Example validation that fail correctly:

    from flask import Flask
    from flask_pydantic import validate
    from pydantic import BaseModel, validator
    
    app = Flask(__name__)
    
    
    class RequestBody(BaseModel):
        format: str
    
    
    
    @app.route("/", methods=["POST"])
    @validate()
    def export(body: RequestBody):
        print(body.format)
        return f"{body.format}"
    
    
    if __name__ == '__main__':
        app.config["TESTING"] = True
        client = app.test_client()
    
        valid_data = {"format": "csv"}
        invalid_data = {"format": [123,123]}
    
        valid_response = client.post("/", json=valid_data)
        print(valid_response.json)
    
        invalid_response = client.post("/", json=invalid_data)
        print(invalid_response.json)
    
    

    response:

    csv
    None
    {'validation_error': {'body_params': [{'loc': ['format'], 'msg': 'str type expected', 'type': 'type_error.str'}]}}
    

    the response details why the validation fails

    Example validation that fails with a JSON serialization error because of an Enum:

    from enum import Enum
    
    from flask import Flask
    from flask_pydantic import validate
    from pydantic import BaseModel
    
    app = Flask(__name__)
    
    
    class Formats(Enum):
        CSV = "csv"
        HTML = "html"
    
    
    class RequestBody(BaseModel):
        format: Formats = Formats.CSV
    
    
    @app.route("/", methods=["POST"])
    @validate()
    def export(body: RequestBody):
        return f"{body.format}"
    
    
    if __name__ == '__main__':
        app.config["TESTING"] = True
        client = app.test_client()
    
        valid_data = {"format": "csv"}
        invalid_data = {"format": "notcsv"}
    
        valid_response = client.post("/", json=valid_data)
        print(valid_response.json)
        invalid_response = client.post("/", json=invalid_data)
        print(invalid_response.json)
    
    

    response (with stack trace):

    Traceback (most recent call last):
      File "/Users/bruno/Developer/flask_pydantic_error/main.py", line 34, in <module>
        invalid_response = client.post("/", json=invalid_data)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/werkzeug/test.py", line 1140, in post
        return self.open(*args, **kw)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/testing.py", line 217, in open
        return super().open(
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/werkzeug/test.py", line 1089, in open
        response = self.run_wsgi_app(request.environ, buffered=buffered)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/werkzeug/test.py", line 956, in run_wsgi_app
        rv = run_wsgi_app(self.application, environ, buffered=buffered)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/werkzeug/test.py", line 1237, in run_wsgi_app
        app_rv = app(environ, start_response)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/app.py", line 2091, in __call__
        return self.wsgi_app(environ, start_response)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/app.py", line 2076, in wsgi_app
        response = self.handle_exception(e)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/app.py", line 2073, in wsgi_app
        response = self.full_dispatch_request()
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/app.py", line 1519, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/app.py", line 1517, in full_dispatch_request
        rv = self.dispatch_request()
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/app.py", line 1503, in dispatch_request
        return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask_pydantic/core.py", line 212, in wrapper
        return make_response(jsonify({"validation_error": err}), status_code)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/json/__init__.py", line 302, in jsonify
        f"{dumps(data, indent=indent, separators=separators)}\n",
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/json/__init__.py", line 132, in dumps
        return _json.dumps(obj, **kwargs)
      File "/Users/bruno/.pyenv/versions/3.10.3/lib/python3.10/json/__init__.py", line 238, in dumps
        **kw).encode(obj)
      File "/Users/bruno/.pyenv/versions/3.10.3/lib/python3.10/json/encoder.py", line 199, in encode
        chunks = self.iterencode(o, _one_shot=True)
      File "/Users/bruno/.pyenv/versions/3.10.3/lib/python3.10/json/encoder.py", line 257, in iterencode
        return _iterencode(o, 0)
      File "/Users/bruno/Developer/flask_pydantic_error/venv/lib/python3.10/site-packages/flask/json/__init__.py", line 51, in default
        return super().default(o)
      File "/Users/bruno/.pyenv/versions/3.10.3/lib/python3.10/json/encoder.py", line 179, in default
        raise TypeError(f'Object of type {o.__class__.__name__} '
    TypeError: Object of type Formats is not JSON serializable
    None
    

    When I was expecting an response of type:

    csv
    None
    {'validation_error': {'body_params': [{'ctx': {'enum_values': ['csv', 'html']}, 'loc': ['format'], 'msg': "value is not a valid enumeration member; permitted: 'csv', 'html'", 'type': 'type_error.enum'}]}}
    

    It seems like the flask's JSONEncoder is used instead of std json. If I modify flask.json.JSONEncoder's default method in order to add:

    if isinstance(o, Enum):
        return o.value
    

    the program functions as expected.

    opened by bruno-robert 2
  • how to use flask getlist mothed

    how to use flask getlist mothed

    if my query string is

    http://url?a[]=1&a[]=2&a[]=3
    

    i want the get the a value is a = [1, 2, 3]

    can i use the query: useModel realize it ?

    class useModel(BaseModel):
        a: List = Field([]) 
    

    is not working

    opened by fainle 0
  • Question: partially populated nested object with required fields

    Question: partially populated nested object with required fields

    Hey all,

    I am trying to understand if the behavior I am seeing is expected, a bug or misconfiguration of my setup.

    The following code uses. Flask-Pydantic = "~=0.9.0"

    There's an endpoint that expects the following simple payload. The address is expected to be fully populated (all fields are required).

    class Address(BaseModel):
        street: str
        city: str
        region: str
        zipcode: str
    
    class Payload(BaseModel):
        username: str
        address: Optional[Address] = None
    
        @root_validator
        def validate_address(cls, values):
            # address is missing from values for partially populated address fields
            if "address" not in values or not values["address"]:
                raise ValueError(f"Full address is required")
            return values
    
    

    This works nicely for fully populated address and when the address is missing in the request (set to None by default).

    However, when I send a partially-populated Address, the field address is missing from the payload :

    Request payload :

    {
    "username": "foo",
    "address": {
                "zipcode": "10001",
            },
        }
    

    flask body:

    { 'username': 'foo' }
    

    Is that expected that when a pydantic object fails to create, it will be dropped ?

    opened by jakubczaplicki 0
Owner
null
Hyperlinks for pydantic models

Hyperlinks for pydantic models In a typical web application relationships between resources are modeled by primary and foreign keys in a database (int

Jaakko Moisio 10 Apr 18, 2022
A RESTful API for creating and monitoring resource components of a hypothetical build system. Built with FastAPI and pydantic. Complete with testing and CI.

diskspace-monitor-CRUD Background The build system is part of a large environment with a multitude of different components. Many of the components hav

Nick Hopewell 67 Dec 14, 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 3, 2023
A Flask extension that enables or disables features based on configuration.

Flask FeatureFlags This is a Flask extension that adds feature flagging to your applications. This lets you turn parts of your site on or off based on

Rachel Greenfield 131 Sep 26, 2022
Flask-vs-FastAPI - Understanding Flask vs FastAPI Web Framework. A comparison of two different RestAPI frameworks.

Flask-vs-FastAPI Understanding Flask vs FastAPI Web Framework. A comparison of two different RestAPI frameworks. IntroductionIn Flask is a popular mic

Mithlesh Navlakhe 1 Jan 1, 2022
Prometheus integration for Starlette.

Starlette Prometheus Introduction Prometheus integration for Starlette. Requirements Python 3.6+ Starlette 0.9+ Installation $ pip install starlette-p

José Antonio Perdiguero 229 Dec 21, 2022
Prometheus integration for Starlette.

Starlette Prometheus Introduction Prometheus integration for Starlette. Requirements Python 3.6+ Starlette 0.9+ Installation $ pip install starlette-p

José Antonio Perdiguero 125 Feb 13, 2021
Keycloak integration for Python FastAPI

FastAPI Keycloak Integration Documentation Introduction Welcome to fastapi-keycloak. This projects goal is to ease the integration of Keycloak (OpenID

Code Specialist 113 Dec 31, 2022
fastapi-mqtt is extension for MQTT protocol

fastapi-mqtt MQTT is a lightweight publish/subscribe messaging protocol designed for M2M (machine to machine) telemetry in low bandwidth environments.

Sabuhi 144 Dec 28, 2022
fastapi-mqtt is extension for MQTT protocol

fastapi-mqtt MQTT is a lightweight publish/subscribe messaging protocol designed for M2M (machine to machine) telemetry in low bandwidth environments.

Sabuhi 23 Feb 11, 2021
FastAPI native extension, easy and simple JWT auth

fastapi-jwt FastAPI native extension, easy and simple JWT auth

Konstantin Chernyshev 19 Dec 12, 2022
An extension library for FastAPI framework

FastLab An extension library for FastAPI framework Features Logging Models Utils Routers Installation use pip to install the package: pip install fast

Tezign Lab 10 Jul 11, 2022
FastAPI Server Session is a dependency-based extension for FastAPI that adds support for server-sided session management

FastAPI Server-sided Session FastAPI Server Session is a dependency-based extension for FastAPI that adds support for server-sided session management.

DevGuyAhnaf 5 Dec 23, 2022
Qwerkey is a social media platform for connecting and learning more about mechanical keyboards built on React and Redux in the frontend and Flask in the backend on top of a PostgreSQL database.

Flask React Project This is the backend for the Flask React project. Getting started Clone this repository (only this branch) git clone https://github

Peter Mai 22 Dec 20, 2022
Flask + marshmallow for beautiful APIs

Flask-Marshmallow Flask + marshmallow for beautiful APIs Flask-Marshmallow is a thin integration layer for Flask (a Python web framework) and marshmal

marshmallow-code 768 Dec 22, 2022
A basic JSON-RPC implementation for your Flask-powered sites

Flask JSON-RPC A basic JSON-RPC implementation for your Flask-powered sites. Some reasons you might want to use: Simple, powerful, flexible and python

Cenobit Technologies 273 Dec 1, 2022
Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-

Kirill Klenov 871 Dec 25, 2022
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 7, 2022
Formatting of dates and times in Flask templates using moment.js.

Flask-Moment This extension enhances Jinja2 templates with formatting of dates and times using moment.js. Quick Start Step 1: Initialize the extension

Miguel Grinberg 358 Nov 28, 2022