🐍 Simple FastAPI template with factory pattern architecture

Overview

logo

Mentioned in Awesome <INSERT LIST NAME> License Twitter

Description

This is a minimalistic and extensible FastAPI template that incorporates factory pattern architecture with divisional folder structure. It's suitable for developing small to medium sized API oriented micro-services. The architecture is similar to what you'd get with Flask's Blueprint.

Features

  • It uses FastAPI framework for API development. FastAPI is a modern, highly performant, web framework for building APIs with Python 3.6+.

  • The APIs are served with Uvicorn server. Uvicorn is a lightning-fast "ASGI" server. It runs asynchronous Python web code in a single process.

  • Gunicorn is used here to manage Uvicorn and run multiple of these concurrent processes. That way, you get the best of concurrency and parallelism.

  • OAuth2 (with hashed password and Bearer with JWT) based authentication

  • CORS (Cross Origin Resource Sharing) enabled.

  • Flask inspired divisional folder structure better decoupling and encapsulation. This is suitable for small to medium backend development.

  • Dockerized using uvicorn-gunicorn-fastapi-docker. This image will set a sensible configuration based on the server it is running on (the amount of CPU cores available) without making sacrifices.

    It has sensible defaults, but you can configure it with environment variables or override the configuration files.

Quickstart

Spin Up the Cookiecutter

  • Install cookiecutter.

  • Go to your project folder and run:

    cookiecutter https://github.com/rednafi/fastapi-nano.git
  • Follow the prompts to generate your project.

    repo [fastapi-nano]:
    api_a [api_a]:
    api_b [api_b]:
    year [2020]:
    fname [Redowan Delowar]:
    email [[email protected]]:
    

Run the Containers

  • Go to your template folder and run:

    docker-compose up -d

Check the APIs

  • To play around with the APIs, go to the following link on your browser:

    http://localhost:5000/docs
    

    This will take you to an UI like below:

    Screenshot from 2020-06-21 22-15-18

  • Press the authorize button on the right and add username and password. The APIs use OAuth2 (with hashed password and Bearer with JWT) based authentication. In this case, the username and password is ubuntu and debian respectively.

    Screenshot from 2020-06-21 22-18-25

    Clicking the authorize button will bring up a screen like this:

    Screenshot from 2020-06-21 22-18-59

  • Then select any of the api_a or api_b APIs and put an integer in the number box and click the authorize button.

    Screenshot from 2020-06-21 22-31-19

  • Hitting the API should give a json response with random integers.

    Screenshot from 2020-06-21 22-32-28

  • Also, notice the curl section in the above screen shot. You can directly use the highlighted curl command in your terminal.

    curl -X GET "http://localhost:5000/api_a/22" -H "accept: application/json" -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1YnVudHUiLCJleHAiOjY4NDg3NDI1MDl9.varo-uXei0kmGkejkfzCtOkWvW6y7ewzaKBj4qZZHWQ"

    This should show a response like this:

    {
    "seed": 22,
    "random_first": 5,
    "random_second": 13
    }
  • To test the GET APIs with Python, you can use a http client library like httpx:

    import httpx
    
    token = (
        "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9."
        + "eyJzdWIiOiJ1YnVudHUiLCJleHAiOjY4NDg3NDI1MDl9."
        + "varo-uXei0kmGkejkfzCtOkWvW6y7ewzaKBj4qZZHWQ"
    )
    
    headers = {
        "accept": "application/json",
        "Authorization": f"Bearer {token}",
    }
    
    with httpx.Client() as client:
        response = client.get("http://localhost:5000/api_a/22", headers=headers)
        print(response.json())

Folder Structure

This shows the folder structure of the default template.

fastapi-nano
├── app                                 # primary application folder
│   ├── apis                            # this houses all the API packages
│   │   ├── api_a                       # api_a package
│   │   │   ├── __init__.py             # empty init file to make the api_a folder a package
│   │   │   ├── mainmod.py              # main module of api_a package
│   │   │   └── submod.py               # submodule of api_a package
│   │   └── api_b                       # api_b package
│   │       ├── __init__.py             # empty init file to make the api_b folder a package
│   │       ├── mainmod.py              # main module of api_b package
│   │       └── submod.py               # submodule of api_b package
│   ├── core                            # this is where the configs live
│   │   ├── auth.py                     # authentication with OAuth2
│   │   ├── config.py                   # sample config file
│   │   └── __init__.py                 # empty init file to make the config folder a package
│   ├── __init__.py                     # empty init file to make the app folder a package
│   ├── main.py                         # main file where the fastAPI() class is called
│   ├── routes                          # this is where all the routes live
│   │   └── views.py                    # file containing the endpoints of api_a and api_b
│   └── tests                           # test package
│       ├── __init__.py                 # empty init file to make the tests folder a package
│       └── test_api.py                 # test files
├── docker-compose.yml                  # docker-compose file
├── Dockerfile                          # dockerfile
├── LICENSE                             # MIT license
├── Makefile                            # Makefile to apply Python linters
├── mypy.ini                            # type checking configs
├── requirements.txt                    # app dependencies
└── requirements-dev.txt                # development dependencies

In the above structure, api_a and api_b are the main packages where the code of the APIs live and they are exposed by the endpoints defined in the routes folder. Here, api_a and api_b have identical logic. Basically these are dummy APIs that take an integer as input and return two random integers between zero and the input value. The purpose of including two identical APIs in the template is to demonstrate how you can decouple the logics of multiple APIs and then assemble their endpoints in the routes directory. The following snippets show the logic behind the dummy APIs.

This is a dummy submodule that houses a function called random_gen which basically generates a dict of random integers.

# This a dummy module
# This gets called in the module_main.py file

import random
from typing import Dict


def rand_gen(num: int) -> Dict[str, int]:
    num = int(num)
    d = {
        "seed": num,
        "random_first": random.randint(0, num),
        "random_second": random.randint(0, num),
    }
    return d

The main_func in the primary module calls the rand_gen function from the submodule.

from typing import Dict

from app.api_a.submod import rand_gen


def main_func(num: int) -> Dict[str, int]:
    d = rand_gen(num)
    return d

The endpoint is exposed like this:

# app/routes/views.py

#... codes regarding authentication ...

# endpoint for api_a (api_b looks identical)
@router.get("/api_a/{num}", tags=["api_a"])
async def view_a(num: int, auth=Depends(get_current_user)) -> Dict[str, int]:
    return main_func_a(num)

So hitting the API with a random integer will give you a response like the following:

{
  "seed": 22,
  "random_first": 27,
  "random_second": 20
}

Further Modifications

  • You can put your own API logics in the shape of api_a and api_b packages. You'll have to add additional directories like api_a and api_b if you need more APIs.

  • Then expose the APIs in the routes/views.py file. You may choose to create multiple views files to organize your endpoints.

  • This template uses OAuth2 based authentication and it's easy to change that. FastAPI docs has a comprehensive list of the available authentication options and instructions on how to use them.

  • During deployment, you may need to change the host name and port number. To do so, just change the values of HOST and PORT variables under the environment section in the docker-compose.yml file.

  • Here, containerization has been done using FastAPI author's python3.8-slim based uvicorn-gunicorn-fastapi-docker image. You may want to use a different base image that caters your usage. A few viable options are listed here.

  • Although this template uses sensible Uvicorn-Gunicorn defaults, it exposes a few configs under the environment section in the docker-compose.yml file. Should you choose to tinker with them, you can do it there. Also, you can use a custom Gunicorn config file and point the location of the custom_gunicorn_conf.py file in the GUNICORN_CONF variable.

Stack

Resources

🍰
Comments
  • ValueError: invalid literal for int() with base 10

    ValueError: invalid literal for int() with base 10

    fastapi | File "/usr/local/lib/python3.8/site-packages/gunicorn/config.py", line 611, in Workers fastapi | default = int(os.environ.get("WEB_CONCURRENCY", 1)) fastapi | ValueError: invalid literal for int() with base 10: '1

    opened by jasonvriends 5
  • README instructions for running locally, update pip packages to resolve error

    README instructions for running locally, update pip packages to resolve error

    Add section and step-by-step instructions for running locally without docker

    ~~There is one step that can be removed (upgrading pip packages to latest to resolve pydantic/fastapi error when app loads login_for_access_token route) once I add those updated requirement.txt's to the PR.~~

    ~~Since I will likely be removing that entire step (and the explanation I have added inline) I will put that here in the PR:~~

    EDIT: that part has been removed and requirements updated to latest with pip-compile.

    Explanation for this error: Without having done this I couldn't launch the uvicorn server without app.core.auth.login_for_access_token() raising an exception: RecursionError: maximum recursion depth exceeded django model inheritance. After some research I found an issue on the FastAPI repo in which the cause was found to be a mismatch in Pydantic and FastAPI versions. I decided to go ahead and update all of the pip packages and have the server running. I will add those updated requirements.txt files to this PR as well. Will likely remove this step once I have added those commits to the PR.

    opened by limsammy 4
  • Live reload Option

    Live reload Option

    Hi, I am trying to use live reload for devlepement. I have added below code in Dockerfile as suggested in uvicorn-gunicorn-fastapi-docker. But when i check it still takes start.sh. Any idea? Thank you very much.

    RUN pip install -r requirements.txt
    
    # copy project
    COPY . /code/
    
    CMD [ "/start-reload.sh" ]  # <-----
    
    # expose port
    EXPOSE 5000
    
    opened by 5un1lk4nn4n 3
  • Starlette Config

    Starlette Config

    Would make sense to use starlette.config.Config instead of os.environ + load_dotenv? Starlette Config does env validation and has builtin load dotenv which would remove the need for python-dotenv. I could send a pull request if its fine.

    opened by guscardvs 2
  • Uvicorn import paths different than main.py’s, difficulties debugging

    Uvicorn import paths different than main.py’s, difficulties debugging

    (I hope I describe this correctly, it is possible that I have a misunderstanding of how imports are resolved)

    Problem: The FastAPI documentation on debugging suggests to call uvicorn directly from main via the IDE/Debugger. However, in this case, fastapi-nano’s imports do not seem to work, as the folder of main.py is the root folder for the module imports with this method of executing the code. So from app.core import auth fails, , from core import auth would work. The imports work when calling uvicorn directly since uvicorn app.main:app (as documented in the readme) seems to make the module resolution uses the folder uvicorn was called from as its root (that is, the project’s main folder with the folder app in it)

    Possible solutions:

    • Assume calling from the /app folder and change paths accordingly
    • Document another way to debug
    • Dont fix/not a significant problem
    opened by jdittrich 2
  • Starlette Config

    Starlette Config

    Commits:

    • feat(config): changed env pkg from python-dotenv to starlette

    Changed config.py to use starlette.config.Config and removed python-dotenv from dependency list. All tests passing. :)

    opened by guscardvs 1
  • Move from pyjwt to python-jose

    Move from pyjwt to python-jose

    FastAPI recommends you to use python-jose instead of Pyjwt.

    You can check it below. https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/?h=python+jose#install-python-jose

    opened by DavidKimDY 1
  • Fix empty volume error when docker-compose up

    Fix empty volume error when docker-compose up

    Newly created templates are showing this error when trying to docker-compose up:

    external volume "" not found
    

    The fix I'm suggesting doesn't require manual volume creation by default.

    opened by ayr-ton 1
  • Bump fastapi from 0.61.1 to 0.65.2 in /{{cookiecutter.repo}}

    Bump fastapi from 0.61.1 to 0.65.2 in /{{cookiecutter.repo}}

    Bumps fastapi from 0.61.1 to 0.65.2.

    Release notes

    Sourced from fastapi's releases.

    0.65.2

    Security fixes

    This change fixes a CSRF security vulnerability when using cookies for authentication in path operations with JSON payloads sent by browsers.

    In versions lower than 0.65.2, FastAPI would try to read the request payload as JSON even if the content-type header sent was not set to application/json or a compatible JSON media type (e.g. application/geo+json).

    So, a request with a content type of text/plain containing JSON data would be accepted and the JSON data would be extracted.

    But requests with content type text/plain are exempt from CORS preflights, for being considered Simple requests. So, the browser would execute them right away including cookies, and the text content could be a JSON string that would be parsed and accepted by the FastAPI application.

    See CVE-2021-32677 for more details.

    Thanks to Dima Boger for the security report! 🙇🔒

    Internal

    0.65.1

    Security fixes

    0.65.0

    Breaking Changes - Upgrade

    • ⬆️ Upgrade Starlette to 0.14.2, including internal UJSONResponse migrated from Starlette. This includes several bug fixes and features from Starlette. PR #2335 by @​hanneskuettner.

    Translations

    Internal

    0.64.0

    Features

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump pydantic from 1.6.1 to 1.6.2 in /{{cookiecutter.repo}}

    Bump pydantic from 1.6.1 to 1.6.2 in /{{cookiecutter.repo}}

    Bumps pydantic from 1.6.1 to 1.6.2.

    Release notes

    Sourced from pydantic's releases.

    v1.6.2 (2021-05-11)

    Security fix: Fix date and datetime parsing so passing either 'infinity' or float('inf') (or their negative values) does not cause an infinite loop, see security advisory CVE-2021-29510.

    Changelog

    Sourced from pydantic's changelog.

    v1.6.2 (2021-05-11)

    • Security fix: Fix date and datetime parsing so passing either 'infinity' or float('inf') (or their negative values) does not cause an infinite loop, See security advisory CVE-2021-29510
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump httpx from 0.23.1 to 0.23.2

    Bump httpx from 0.23.1 to 0.23.2

    Bumps httpx from 0.23.1 to 0.23.2.

    Release notes

    Sourced from httpx's releases.

    Version 0.23.2

    0.23.2 (2nd Jan, 2023)

    Added

    • Support digest auth nonce counting to avoid multiple auth requests. (#2463)

    Fixed

    • Multipart file uploads where the file length cannot be determine now use chunked transfer encoding, rather than loading the entire file into memory in order to determine the Content-Length. (#2382)
    • Raise TypeError if content is passed a dict-instance. (#2495)
    • Partially revert the API breaking change in 0.23.1, which removed RawURL. We continue to expose a url.raw property which is now a plain named-tuple. This API is still expected to be deprecated, but we will do so with a major version bump. (#2481)
    Changelog

    Sourced from httpx's changelog.

    0.23.2 (2nd Jan, 2023)

    Added

    • Support digest auth nonce counting to avoid multiple auth requests. (#2463)

    Fixed

    • Multipart file uploads where the file length cannot be determine now use chunked transfer encoding, rather than loading the entire file into memory in order to determine the Content-Length. (#2382)
    • Raise TypeError if content is passed a dict-instance. (#2495)
    • Partially revert the API breaking change in 0.23.1, which removed RawURL. We continue to expose a url.raw property which is now a plain named-tuple. This API is still expected to be deprecated, but we will do so with a major version bump. (#2481)
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies python 
    opened by dependabot[bot] 0
Releases(0.2)
  • 0.2(Oct 31, 2022)

  • 0.1.1(Jul 4, 2022)

  • 0.1(Feb 25, 2022)

    You can now test the application by pulling the image from Dockerhub. To do so, run:

    docker run -p 5000:5000 --expose 5000 rednafi/fastapi-nano:0.1
    

    Then:

    curl -X GET http://localhost:5000/ | jq
    
    {
      "info": "This is the index page of fastapi-nano. You probably want to go to 'http://<hostname:port>/docs'."
    }
    
    Source code(tar.gz)
    Source code(zip)
Owner
Redowan Delowar
Hacking healthcare @DendiSoftware . Writing & talking about—Statistics, Machine Learning, System Arch, APIs, Redis, Docker, Python, JavaScript, etc.
Redowan Delowar
🐍 Simple FastAPI template with factory pattern architecture

Description This is a minimalistic and extensible FastAPI template that incorporates factory pattern architecture with divisional folder structure. It

Redowan Delowar 551 Dec 24, 2022
Instrument your FastAPI app

Prometheus FastAPI Instrumentator A configurable and modular Prometheus Instrumentator for your FastAPI. Install prometheus-fastapi-instrumentator fro

Tim Schwenke 441 Jan 05, 2023
fastapi-admin2 is an upgraded fastapi-admin, that supports ORM dialects, true Dependency Injection and extendability

FastAPI2 Admin Introduction fastapi-admin2 is an upgraded fastapi-admin, that supports ORM dialects, true Dependency Injection and extendability. Now

Glib 14 Dec 05, 2022
Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

GraphQL Python 1.3k Dec 31, 2022
Simple example of FastAPI + Celery + Triton for benchmarking

You can see the previous work from: https://github.com/Curt-Park/producer-consumer-fastapi-celery https://github.com/Curt-Park/triton-inference-server

Jinwoo Park (Curt) 37 Dec 29, 2022
implementation of deta base for FastAPIUsers

FastAPI Users - Database adapter for Deta Base Ready-to-use and customizable users management for FastAPI Documentation: https://fastapi-users.github.

2 Aug 15, 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
Full stack, modern web application generator. Using FastAPI, PostgreSQL as database, Docker, automatic HTTPS and more.

Full Stack FastAPI and PostgreSQL - Base Project Generator Generate a backend and frontend stack using Python, including interactive API documentation

Sebastián Ramírez 10.8k Jan 08, 2023
An alternative implement of Imjad API | Imjad API 的开源替代

HibiAPI An alternative implement of Imjad API. Imjad API 的开源替代. 前言 由于Imjad API这是什么?使用人数过多, 致使调用超出限制, 所以本人希望提供一个开源替代来供社区进行自由的部署和使用, 从而减轻一部分该API的使用压力 优势

Mix Technology 450 Dec 29, 2022
Signalling for FastAPI.

fastapi-signals Signalling for FastAPI.

Henshal B 7 May 04, 2022
Single Page App with Flask and Vue.js

Developing a Single Page App with FastAPI and Vue.js Want to learn how to build this? Check out the post. Want to use this project? Build the images a

91 Jan 05, 2023
:rocket: CLI tool for FastAPI. Generating new FastAPI projects & boilerplates made easy.

Project generator and manager for FastAPI. Source Code: View it on Github Features 🚀 Creates customizable project boilerplate. Creates customizable a

Yagiz Degirmenci 1k Jan 02, 2023
Sample-fastapi - A sample app using Fastapi that you can deploy on App Platform

Getting Started We provide a sample app using Fastapi that you can deploy on App

Erhan BÜTE 2 Jan 17, 2022
A rate limiter for Starlette and FastAPI

SlowApi A rate limiting library for Starlette and FastAPI adapted from flask-limiter. Note: this is alpha quality code still, the API may change, and

Laurent Savaete 562 Jan 01, 2023
FastAPI simple cache

FastAPI Cache Implements simple lightweight cache system as dependencies in FastAPI. Installation pip install fastapi-cache Usage example from fastapi

Ivan Sushkov 188 Dec 29, 2022
A Python framework to build Slack apps in a flash with the latest platform features.

Bolt for Python A Python framework to build Slack apps in a flash with the latest platform features. Read the getting started guide and look at our co

SlackAPI 684 Jan 09, 2023
A simple Redis Streams backed Chat app using Websockets, Asyncio and FastAPI/Starlette.

redis-streams-fastapi-chat A simple demo of Redis Streams backed Chat app using Websockets, Python Asyncio and FastAPI/Starlette. Requires Python vers

ludwig404 135 Dec 19, 2022
🐍Pywork is a Yeoman generator to scaffold a Bare-bone Python Application

Pywork python app yeoman generator Yeoman | Npm Pywork | Home PyWork is a Yeoman generator for a basic python-worker project that makes use of Pipenv,

Vu Tran 10 Dec 16, 2022
Keycloack plugin for FastApi.

FastAPI Keycloack Keycloack plugin for FastApi. Your aplication receives the claims decoded from the access token. Usage Run keycloak on port 8080 and

Elber 4 Jun 24, 2022
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