FastAPI framework plugins

Overview

Plugins for FastAPI framework, high performance, easy to learn, fast to code, ready for production

Build Status Coverage Package version Join the chat at https://gitter.im/tiangolo/fastapi

fastapi-plugins

FastAPI framework plugins

Changes

See release notes

Installation

pip install fastapi-plugins
pip install fastapi-plugins[memcached]
pip install fastapi-plugins[all]

Plugins

Cache

Memcached

Valid variable are

  • MEMCACHED_HOST - Memcached server host.
  • MEMCACHED_PORT - Memcached server port. Default is 11211.
  • MEMCACHED_POOL_MINSIZE - Minimum number of free connection to create in pool. Default is 1.
  • MEMCACHED_POOL_SIZE - Maximum number of connection to keep in pool. Default is 10. Must be greater than 0. None is disallowed.
  • MEMCACHED_PRESTART_TRIES - The number tries to connect to the a Memcached instance.
  • MEMCACHED_PRESTART_WAIT - The interval in seconds to wait between connection failures on application start.
Example
    # run with `uvicorn demo_app:app`
    import typing
    import fastapi
    import pydantic
    
    from fastapi_plugins.memcached import MemcachedSettings
    from fastapi_plugins.memcached import MemcachedClient
    from fastapi_plugins.memcached import memcached_plugin
    from fastapi_plugins.memcached import depends_memcached
    
    class AppSettings(OtherSettings, MemcachedSettings):
        api_name: str = str(__name__)
    
    app = fastapi.FastAPI()
    config = AppSettings()
    
    @app.get("/")
    async def root_get(
            cache: MemcachedClient=fastapi.Depends(depends_memcached),
    ) -> typing.Dict:
        await cache.set(b'Hello', b'World')
        await cache.get(b'Hello')
        return dict(ping=await cache.ping())
    
    @app.on_event('startup')
    async def on_startup() -> None:
        await memcached_plugin.init_app(app, config=config)
        await memcached_plugin.init()
    
    @app.on_event('shutdown')
    async def on_shutdown() -> None:
        await memcached_plugin.terminate()

Redis

Supports

  • single instance
  • sentinel

Valid variable are

  • REDIS_TYPE
    • redis - single Redis instance
    • sentinel - Redis cluster
  • REDIS_URL - URL to connect to Redis server. Example redis://user:[email protected]:6379/2. Supports protocols redis://, rediss:// (redis over TLS) and unix://.
  • REDIS_HOST - Redis server host.
  • REDIS_PORT - Redis server port. Default is 6379.
  • REDIS_PASSWORD - Redis password for server.
  • REDIS_DB - Redis db (zero-based number index). Default is 0.
  • REDIS_CONNECTION_TIMEOUT - Redis connection timeout. Default is 2.
  • REDIS_POOL_MINSIZE - Minimum number of free connection to create in pool. Default is 1.
  • REDIS_POOL_MAXSIZE - Maximum number of connection to keep in pool. Default is 10. Must be greater than 0. None is disallowed.
  • REDIS_SENTINELS - List or a tuple of Redis sentinel addresses.
  • REDIS_SENTINEL_MASTER - The name of the master server in a sentinel configuration. Default is mymaster.
  • REDIS_PRESTART_TRIES - The number tries to connect to the a Redis instance.
  • REDIS_PRESTART_WAIT - The interval in seconds to wait between connection failures on application start.
Example
    # run with `uvicorn demo_app:app`
    import typing
    import aioredis
    import fastapi
    import pydantic
    import fastapi_plugins
    
    class AppSettings(OtherSettings, fastapi_plugins.RedisSettings):
        api_name: str = str(__name__)
    
    app = fastapi.FastAPI()
    config = AppSettings()
    
    @app.get("/")
    async def root_get(
            cache: aioredis.Redis=fastapi.Depends(fastapi_plugins.depends_redis),
    ) -> typing.Dict:
        return dict(ping=await cache.ping())
    
    @app.on_event('startup')
    async def on_startup() -> None:
        await fastapi_plugins.redis_plugin.init_app(app, config=config)
        await fastapi_plugins.redis_plugin.init()
    
    @app.on_event('shutdown')
    async def on_shutdown() -> None:
        await fastapi_plugins.redis_plugin.terminate()
Example with Docker Compose - Redis
version: '3.7'
services:
  redis:
    image: redis
    ports:
      - "6379:6379"
  demo_fastapi_plugin:
    image:    demo_fastapi_plugin
    environment:
      - REDIS_TYPE=redis
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    ports:
      - "8000:8000"
Example with Docker Compose - Redis Sentinel
version: '3.7'
services:
  ...
  redis-sentinel:
    ports:
      - "26379:26379"
    environment:
      - ...
    links:
      - redis-master
      - redis-slave
  demo_fastapi_plugin:
    image:    demo_fastapi_plugin
    environment:
      - REDIS_TYPE=sentinel
      - REDIS_SENTINELS=redis-sentinel:26379
    ports:
      - "8000:8000"

Scheduler

Simple schedule an awaitable job as a task.

  • long running async functions (e.g. monitor a file a system or events)
  • gracefully cancel spawned tasks

Valid variable are:

  • AIOJOBS_CLOSE_TIMEOUT - The timeout in seconds before canceling a task.
  • AIOJOBS_LIMIT - The number of concurrent tasks to be executed.
  • AIOJOBS_PENDING_LIMIT - The number of pending jobs (waiting fr execution).
# run with `uvicorn demo_app:app`
import ...
import fastapi_plugins

class AppSettings(OtherSettings, fastapi_plugins.RedisSettings, fastapi_plugins.SchedulerSettings):
    api_name: str = str(__name__)

app = fastapi.FastAPI()
config = AppSettings()

@app.post("/jobs/schedule/<timeout>")
async def job_post(
    timeout: int=fastapi.Query(..., title='the job sleep time'),
    cache: aioredis.Redis=fastapi.Depends(fastapi_plugins.depends_redis),
    scheduler: aiojobs.Scheduler=fastapi.Depends(fastapi_plugins.depends_scheduler),  # @IgnorePep8
) -> str:
    async def coro(job_id, timeout, cache):
        await cache.set(job_id, 'processing')
        try:
            await asyncio.sleep(timeout)
            if timeout == 8:
                raise Exception('ugly error')
        except asyncio.CancelledError:
            await cache.set(job_id, 'canceled')
        except Exception:
            await cache.set(job_id, 'erred')
        else:
            await cache.set(job_id, 'success')

    job_id = str(uuid.uuid4()).replace('-', '')
    await cache.set(job_id, 'pending')
    await scheduler.spawn(coro(job_id, timeout, cache))
    return job_id

@app.get("/jobs/status/<job_id>")
async def job_get(
    job_id: str=fastapi.Query(..., title='the job id'),
    cache: aioredis.Redis=fastapi.Depends(fastapi_plugins.depends_redis),
) -> typing.Dict:
    status = await cache.get(job_id)
    if status is None:
        raise fastapi.HTTPException(
            status_code=starlette.status.HTTP_404_NOT_FOUND,
            detail='Job %s not found' % job_id
        )
    return dict(job_id=job_id, status=status)

@app.on_event('startup')
async def on_startup() -> None:
    await fastapi_plugins.redis_plugin.init_app(app, config=config)
    await fastapi_plugins.redis_plugin.init()
    await fastapi_plugins.scheduler_plugin.init_app(app=app, config=config)
    await fastapi_plugins.scheduler_plugin.init()

@app.on_event('shutdown')
async def on_shutdown() -> None:
    await fastapi_plugins.scheduler_plugin.terminate()
    await fastapi_plugins.redis_plugin.terminate()

... more already in progress ...

Development

Issues and suggestions are welcome through issues

License

This project is licensed under the terms of the MIT license.

Comments
  • Why are you not closing the database connection before shutdown?

    Why are you not closing the database connection before shutdown?

    We (our team) were trying with your library, and stumbled on this "missing" feature.

    It's important to close the connections for a truly graceful shutdown. Was that a project decision? Didn't you just think about it?

    More important: would you be willing to receive a proposal for this implementation?

    question 
    opened by azisaka 6
  • Fix redis_url ignored

    Fix redis_url ignored

    redis_url setting is currently ignored and DSN is always built by using separate parameters

    This is just a PoC, I will provide a more thorough PR in the next days

    bug 
    opened by yakky 6
  • Remove __all__ in __init__

    Remove __all__ in __init__

    Hi, I noticed this project uses __all__ for most of its modules. However, in fastapi_plugins/__init__.py I see __all__ = [] which causes my editor to warn with things like 'RedisSettings' is not declared in __all__. I decided to simply remove __all__ from there since it is optional. Alternatively, I could combine __all__ from each of the imported modules.

    What do you think?

    bug 
    opened by MatthewScholefield 5
  •  AttributeError: 'State' object has no attribute 'REDIS'

    AttributeError: 'State' object has no attribute 'REDIS'

    Pytest API testing does not work if a function has a cache dependency.

    Here is the example

    @router.post("/login/", response_model=Token)
    async def login(form_data: OAuth2PasswordRequestForm = Depends(),
                    cache: aioredis.Redis = Depends(fastapi_plugins.depends_redis)):
                    ...
                    await cache.setex("SomeKey", 300, "SomeValue")
    
    
        @pytest.mark.asyncio
        async def test_login_view_pass(self, client):
            data = UserInput(**self.__generate_data())
            await user_create(data)
            response = await client.post(f"{settings.API_VERSION}/users/login/",
                                         data={"username": data.username,
                                               "password": data.password},
                                         headers={"Content-Type": "application/x-www-form-urlencoded"})
            assert response.status_code == status.HTTP_200_OK
    
    
    self = <starlette.datastructures.State object at 0x7f10ceccd610>, key = 'REDIS'
    
        def __getattr__(self, key: typing.Any) -> typing.Any:
            try:
                return self._state[key]
            except KeyError:
                message = "'{}' object has no attribute '{}'"
    >           raise AttributeError(message.format(self.__class__.__name__, key))
    E           AttributeError: 'State' object has no attribute 'REDIS'
    
    /usr/local/lib/python3.8/site-packages/starlette/datastructures.py:672: AttributeError
    

    Is there any way to solve this issue ?

    opened by Koshkaj 4
  • aioredis version issue: `AttributeError: module 'aioredis' has no attribute 'create_redis_pool'`

    aioredis version issue: `AttributeError: module 'aioredis' has no attribute 'create_redis_pool'`

    aioredis does not import anymore create_redis_pool method in its __init__ at least after v1.3.1 see here.

    Unfortunately fastapi-plugins is still using that method in _redis.init() and it defines aioredis>=1.3.* in its setup.py see here

    That can cause to raise the following exception in case aioredis > 1.3.1 has been installed in your system

    AttributeError: module 'aioredis' has no attribute 'create_redis_pool'
    
    bug 
    opened by kinderp 3
  • The startup example codes do not work, cannot `Depends`  fastapi_plugins.depends_redis

    The startup example codes do not work, cannot `Depends` fastapi_plugins.depends_redis

    I test fastapi-plugins using the example codes ,but it corrupts with

    fastapi.exceptions.FastAPIError: Invalid args for response field! 
    Hint: check that <class 'starlette.requests.HTTPConnection'> is a valid pydantic field type
    

    the codes all go here

    import fastapi, fastapi_plugins
    import aioredis, pydantic, typing
    
    @fastapi_plugins.registered_configuration
    class AppSettings(
            fastapi_plugins.ControlSettings,
            fastapi_plugins.RedisSettings,
            fastapi_plugins.SchedulerSettings
    ):
        api_name: str = str(__name__)
    
    
    app = fastapi.FastAPI()
    config = fastapi_plugins.get_config()
    
    @app.get("/")
    async def root_get(
            cache: aioredis.Redis=fastapi.Depends(fastapi_plugins.depends_redis), # TODO corrupts here,
            conf: pydantic.BaseSettings=fastapi.Depends(fastapi_plugins.depends_config) # noqa E501
    ) -> typing.Dict:
        return dict(ping=await cache.ping(), api_name=conf.api_name)
    
    @app.on_event('startup')
    async def on_startup() -> None:
        await fastapi_plugins.config_plugin.init_app(app, config)
        await fastapi_plugins.config_plugin.init()
        await fastapi_plugins.redis_plugin.init_app(app, config=config)
        await fastapi_plugins.redis_plugin.init()
        await fastapi_plugins.scheduler_plugin.init_app(app=app, config=config)
        await fastapi_plugins.scheduler_plugin.init()
        await fastapi_plugins.control_plugin.init_app(app, config=config, version="0.0.1", environ=config.dict())
        await fastapi_plugins.control_plugin.init()
    
    
    @app.on_event('shutdown')
    async def on_shutdown() -> None:
        await fastapi_plugins.control_plugin.terminate()
        await fastapi_plugins.scheduler_plugin.terminate()
        await fastapi_plugins.redis_plugin.terminate()
        await fastapi_plugins.config_plugin.terminate()
    

    packages info:

    pip show fastapi-plugins
    #Name: fastapi-plugins
    #Version: 0.8.1
    
    pip show fastapi
    #Name: fastapi
    #Version: 0.54.2
    

    what have I missed?

    opened by tearf001 2
Releases(0.11.0)
Owner
RES
software engineer :: python && c++
RES
Simple notes app backend using Python's FastAPI framework.

my-notes-app Simple notes app backend using Python's FastAPI framework. Route "/": User login (GET): return 200, list of all of their notes; User sign

José Gabriel Mourão Bezerra 2 Sep 17, 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
京东图片点击验证码识别

京东图片验证码识别 本项目是@yqchilde 大佬的 JDMemberCloseAccount 识别图形验证码(#45)思路验证,若你也有思路可以提交Issue和PR也可以在 @yqchilde 的 TG群 找到我 声明 本脚本只是为了学习研究使用 本脚本除了采集处理验证码图片没有其他任何功能,也

AntonVanke 37 Dec 22, 2022
Complete Fundamental to Expert Codes of FastAPI for creating API's

FastAPI FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3 based on standard Python type hints. The key featu

Pranav Anand 1 Nov 28, 2021
Hook Slinger acts as a simple service that lets you send, retry, and manage event-triggered POST requests, aka webhooks

Hook Slinger acts as a simple service that lets you send, retry, and manage event-triggered POST requests, aka webhooks. It provides a fully self-contained docker image that is easy to orchestrate, m

Redowan Delowar 96 Jan 02, 2023
FastAPI Socket.io with first-class documentation using AsyncAPI

fastapi-sio Socket.io FastAPI integration library with first-class documentation using AsyncAPI The usage of the library is very familiar to the exper

Marián Hlaváč 9 Jan 02, 2023
FastAPI CRUD template using Deta Base

Deta Base FastAPI CRUD FastAPI CRUD template using Deta Base Setup Install the requirements for the CRUD: pip3 install -r requirements.txt Add your D

Sebastian Ponce 2 Dec 15, 2021
Light, Flexible and Extensible ASGI API framework

Starlite Starlite is a light and flexible ASGI API framework. Using Starlette and pydantic as foundations. Check out the Starlite documentation 📚 Cor

1.5k Jan 04, 2023
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
Signalling for FastAPI.

fastapi-signals Signalling for FastAPI.

Henshal B 7 May 04, 2022
A web application using [FastAPI + streamlit + Docker] Neural Style Transfer (NST) refers to a class of software algorithms that manipulate digital images

Neural Style Transfer Web App - [FastAPI + streamlit + Docker] NST - application based on the Perceptual Losses for Real-Time Style Transfer and Super

Roman Spiridonov 3 Dec 05, 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
FastAPI interesting concepts.

fastapi_related_stuffs FastAPI interesting concepts. FastAPI version :- 0.70 Python3 version :- 3.9.x Steps Test Django Like settings export FASTAPI_S

Mohd Mujtaba 3 Feb 06, 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
CURSO PROMETHEUS E GRAFANA: Observability in a real world

Curso de monitoração com o Prometheus Esse curso ensina como usar o Prometheus como uma ferramenta integrada de monitoração, entender seus conceitos,

Rafael Cirolini 318 Dec 23, 2022
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
This repository contains learning resources for Python Fast API Framework and Docker

This repository contains learning resources for Python Fast API Framework and Docker, Build High Performing Apps With Python BootCamp by Lux Academy and Data Science East Africa.

Harun Mbaabu Mwenda 23 Nov 20, 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
FastAPI pagination

FastAPI Pagination Installation # Basic version pip install fastapi-pagination # All available integrations pip install fastapi-pagination[all] Avail

Yurii Karabas 561 Jan 07, 2023
Dead-simple mailer micro-service for static websites

Mailer Dead-simple mailer micro-service for static websites A free and open-source software alternative to contact form services such as FormSpree, to

Romain Clement 42 Dec 21, 2022