modern-di 2.28.0 — the integration kit
Back-compatible: no behavior flips, no new warnings, no changes to any
existing public symbol. This release adds one new module,
modern_di.integrations, for framework-integration authors — nothing else
changes.
Feature
-
modern_di.integrations— shared primitives for building an
integration. Every framework adapter (FastAPI, Starlette, gRPC, ...) has
hand-rolled the same framework-agnostic skeleton: deriving a child
container's scope/context from a connection, and scanning a handler's
Annotatedhints for DI markers. This module extracts that skeleton so
adapters can compose it instead of duplicating it.Connection derivation — never wraps
Container.build_child_container
itself, only computes what to pass it:from modern_di import integrations match = integrations.classify_connection(connection, (request_provider, websocket_provider)) child = root.build_child_container( scope=match.scope if match else None, context=match.context if match else None, )
For a single connection kind with no dispatch,
integrations.bind(provider, connection)
skips straight to the derivation.The
Annotated-marker injector:from modern_di import integrations service: typing.Annotated[Service, integrations.from_di(Deps.service)] markers = integrations.parse_markers(handler) # decoration time resolved = integrations.resolve_markers(child, markers) # call time
integrations.is_injected/mark_injectedguard against double-wrapping a
handler an auto-inject sweep visits more than once.See architecture/integration-kit.md
for the full design, and the updated
writing-integrations guide
for how an adapter composes these.
Downstream
- No action needed for existing integrations — this release changes
nothing they already depend on. - Integration authors adopting the kit (starlette is next, one adapter
per PR per the rollout plan): bump the floor tomodern-di>=2.28,<3to
importmodern_di.integrations.
Internals
- 100% line coverage maintained across Python 3.10–3.14;
ruffandty
clean; docs built undermkdocs --strictin CI. - Built via
subagent-driven-development: 9 planned tasks, each with an
independent spec+quality review; a whole-branch review before merge.