README.md

July 12, 2026 ยท View on GitHub

modern-di-starlette

PyPI version Supported Python versions Downloads Coverage CI License GitHub stars uv Ruff ty

Modern-DI integration for Starlette.

Full guide: Starlette integration docs

Installation

uv add modern-di-starlette      # or: pip install modern-di-starlette

Usage

setup_di registers the container, composes the lifespan, and installs middleware that builds a per-connection child container. Decorate an endpoint with @inject and mark parameters with FromDI to receive resolved dependencies. Starlette has no native DI, so @inject is required (there is no Depends).

import dataclasses
import typing

from modern_di import Container, Group, Scope, providers
from modern_di_starlette import FromDI, inject, setup_di
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import JSONResponse
from starlette.routing import Route


@dataclasses.dataclass(kw_only=True)
class Settings:
    debug: bool = True


@dataclasses.dataclass(kw_only=True)
class UserService:
    settings: Settings  # auto-injected by type


class Dependencies(Group):
    settings = providers.Factory(scope=Scope.APP, creator=Settings)
    user_service = providers.Factory(scope=Scope.REQUEST, creator=UserService)


@inject
async def homepage(
    request: Request,
    service: typing.Annotated[UserService, FromDI(Dependencies.user_service)],
) -> JSONResponse:
    return JSONResponse({"debug": service.settings.debug})


app = Starlette(routes=[Route("/", homepage)])
container = Container(groups=[Dependencies], validate=True)
setup_di(app, container)

An HTTP request opens a Scope.REQUEST child container; a WebSocket connection opens a Scope.SESSION one, both built by the middleware before your handler runs. The connection starlette.requests.Request / starlette.websockets.WebSocket are resolvable within DI via the pre-built starlette_request_provider / starlette_websocket_provider context providers.

API

SymbolDescription
setup_di(app, container)Registers the container on app.state, composes the lifespan (opens/closes the container), and installs the middleware that builds a per-connection child container; returns the container
FromDI(dependency)Inert marker (used with @inject) that resolves a provider or type from the per-connection child container
inject(handler)Decorator for an async def handler taking a Request or WebSocket; resolves its FromDI-annotated parameters
fetch_di_container(app)Returns the root Container stored on app.state
starlette_request_providerContextProvider for starlette.requests.Request (REQUEST scope), auto-registered
starlette_websocket_providerContextProvider for starlette.websockets.WebSocket (SESSION scope), auto-registered

๐Ÿ“ฆ 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.