README.md
July 6, 2026 ยท View on GitHub
Modern-DI integration for Litestar.
Usage example: litestar-sqlalchemy-template
Installation
uv add modern-di-litestar # or: pip install modern-di-litestar
Usage
1. Define providers
import dataclasses
from modern_di import Group, Scope, providers
@dataclasses.dataclass(kw_only=True)
class Database:
url: str
@dataclasses.dataclass(kw_only=True)
class UserRepository:
db: Database
class AppDependencies(Group):
database = providers.Factory(creator=Database, kwargs={"url": "sqlite:///app.db"})
user_repo = providers.Factory(scope=Scope.REQUEST, creator=UserRepository, bound_type=None)
2. Wire the plugin
import litestar
from modern_di import Container
from modern_di_litestar import ModernDIPlugin
groups = [AppDependencies]
app = litestar.Litestar(
plugins=[ModernDIPlugin(Container(groups=groups, validate=True), autowired_groups=groups)],
)
Passing autowired_groups to ModernDIPlugin auto-registers each provider as a Litestar dependency keyed by its attribute name (database, user_repo), so routes can declare them directly as parameters.
3. Inject into routes
Using FromDI (explicit, per-route)
from modern_di_litestar import FromDI
@litestar.get(
"/users",
dependencies={"repo": FromDI(AppDependencies.user_repo)},
)
async def list_users(repo: UserRepository) -> list[str]:
...
FromDI accepts either a provider instance (AppDependencies.user_repo) or a type (UserRepository).
Using auto-wired group names (implicit)
When autowired_groups is passed to ModernDIPlugin, provider names become available as route parameters directly:
@litestar.get("/users")
async def list_users(user_repo: UserRepository) -> list[str]:
...
4. Access the raw request or websocket via DI
from modern_di_litestar import litestar_request_provider, litestar_websocket_provider
class AppDependencies(Group):
...
request_method = providers.Factory(
scope=Scope.REQUEST,
creator=lambda request: request.method,
bound_type=None,
)
litestar_request_provider and litestar_websocket_provider are pre-built ContextProvider instances that make the current Request / WebSocket objects resolvable within DI.
5. Sub-request (action) scopes
For work that should live shorter than a request, build a child container inside a route:
@litestar.get("/")
async def handler(di_container: Container) -> None:
action_container = di_container.build_child_container()
result = action_container.resolve_provider(AppDependencies.some_action_scoped_factory)
6. Retrieve the app-level container
from modern_di_litestar import fetch_di_container
container = fetch_di_container(app)
API
| Symbol | Description |
|---|---|
ModernDIPlugin(container, autowired_groups=None) | Litestar InitPlugin โ wires the DI container into app lifecycle |
FromDI(provider) | Returns a Litestar Provide that resolves a provider per request |
litestar_request_provider | ContextProvider for the current litestar.Request |
litestar_websocket_provider | ContextProvider for the current litestar.WebSocket |
fetch_di_container(app) | Retrieves the root container from app.state |
build_di_container | Litestar dependency (registered as di_container) โ yields a scoped child container per request |
๐ฆ PyPI
๐ License
Part of modern-python
Built on modern-di, a dependency-injection framework with IoC container and scopes.
Browse the full list of templates and libraries in
modern-python โ see the org profile for the categorized index.