python-injector integration for FastAPI
Project description
FastAPI Injector
Integrates injector with FastAPI.
Github: https://github.com/matyasrichter/fastapi-injector
PyPI: https://pypi.org/project/fastapi-injector/
Installation
pip install fastapi-injector
Usage
When creating your FastAPI app, attach the injector to it:
# app.py
from fastapi import FastAPI
from injector import Injector
from fastapi_injector import attach_injector
def create_app(injector: Injector) -> FastAPI:
app = FastAPI()
app.include_router(...)
...
attach_injector(app, injector)
return app
Then, use Injected
in your routes. Under the hood, Injected
is Depends
, so you can use it anywhere Depends
can be used. In the following example, InterfaceType
is
something you've bound an implementation to in your injector instance.
from fastapi import APIRouter
from fastapi_injector import Injected
router = APIRouter()
@router.get("/")
async def get_root(integer: int = Injected(InterfaceType)):
return integer
A more complete example could look like this (your FastAPI code only depends on InterfaceType
,
its implementation only depends on a domain layer port etc.):
# ------------------------
# interface.py
import abc
from abc import abstractmethod
class SomeInterface(abc.ABC):
@abstractmethod
async def create_some_entity(self) -> None:
"""Creates and saves an entity."""
# ------------------------
# service.py
import abc
from .interface import SomeInterface
class SomeSavePort(abc.ABC):
@abc.abstractmethod
async def save_something(self, something: Entity) -> None:
"""Saves an entity."""
class SomeService(SomeInterface):
def __init__(self, save_port: Inject[SomeSavePort]):
self.save_port = save_port
async def create_some_entity(self) -> None:
entity = Entity(attr1=1, attr2=2)
await self.save_port.save_something(entity)
# ------------------------
# repository.py
from .service import SomeSavePort
class SomeRepository(SomeSavePort):
async def save_something(self, something: Entity) -> None:
# code that saves the entity to the DB
Testing with fastapi-injector
To use your app in tests with overridden dependencies, modify the injector before each test:
# ------------------------
# app entrypoint
import pytest
from injector import Injector
app = create_app(inj)
if __name__ == "__main__":
uvicorn.run("app", ...)
# ------------------------
# composition root
def create_injector() -> Injector:
inj = Injector()
# note that this still gets executed,
# so if you need to get rid of a DB connection, for example,
# you would need to use a callable provider.
inj.binder.bind(int, 1)
return inj
# ------------------------
# tests
from fastapi import FastAPI
from fastapi.testclient import TestClient
from path.to.app.factory import create_app
@pytest.fixture
def app() -> FastAPI:
inj = Injector()
inj.binder.bind(int, 2)
return create_app(inj)
def some_test(app: FastAPI):
# use test client with the new app
client = TestClient(app)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Hashes for fastapi_injector-0.1.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3325526f020ff3e647df3c91f10e0b7891f1c0a76befe06b4470a6f427e36515 |
|
MD5 | 1bef2f33e1965cff5ea9fc71bf6f617b |
|
BLAKE2b-256 | 1a4c23b06141e3d086e3e53c78fcedfc71c7ae0731e62c15012e0d1e3d29941a |