FastDepends
FastDepends is a lightweight Python library providing a dependency injection system, extracted and refined from FastAPI's core logic. It allows developers to use FastAPI-like dependency resolution and type casting in any Python project, whether synchronous or asynchronous, without the HTTP-specific components. Currently at version 3.0.8, the library maintains an active development pace with frequent updates and bug fixes.
Warnings
- breaking Version 3.0.0 introduced explicit serializer selection. If you were implicitly relying on Pydantic v1 behavior, you now need to explicitly pass a serializer instance (e.g., `PydanticSerializer()`) to the `@inject` decorator.
- gotcha When running in a synchronous context, only synchronous dependencies are available. Asynchronous dependencies can only be resolved when the `@inject`'ed function itself is asynchronous and an event loop is running.
- gotcha Dependencies are cached by default within a single call to an `@inject`'ed function. This means if a dependency is called multiple times by different sub-dependencies within the same top-level `@inject` call, it will only execute once and return the cached result.
- gotcha FastDepends leverages Pydantic for validation and type casting by default. Mixing FastDepends with projects or dependencies that are strictly tied to Pydantic v1 might lead to compatibility issues, especially if the new explicit serializer system is not used correctly.
Install
-
pip install fast-depends -
pip install fast-depends[pydantic] -
pip install fast-depends[msgspec]
Imports
- inject
from fast_depends import inject
- Depends
from fast_depends import Depends
- ContextDepends
from fast_depends import ContextDepends
- PydanticSerializer
from fast_depends.pydantic import PydanticSerializer
- MsgSpecSerializer
from fast_depends.msgspec import MsgSpecSerializer
Quickstart
from fast_depends import inject, Depends
def get_user_id() -> int:
return 42
@inject
def process_data(data: str, user_id: int = Depends(get_user_id)) -> str:
return f"Processing '{data}' for user {user_id}"
result = process_data("hello world")
print(result)
# Async example (requires an event loop)
import asyncio
async def async_get_greeting() -> str:
await asyncio.sleep(0.1)
return "Hello"
@inject
async def greet_user(name: str, greeting: str = Depends(async_get_greeting)) -> str:
return f"{greeting}, {name}!"
async def main_async():
async_result = await greet_user("Alice")
print(async_result)
# To run the async example in a synchronous environment:
# asyncio.run(main_async())