Releases: modern-python/modern-di-aiohttp
Release list
2.2.0
modern-di-aiohttp 2.2.0 — adopt the modern-di integration kit
Maintenance release. No public API change — FromDI, inject,
setup_di, fetch_di_container, fetch_request_container, and the
connection providers keep their signatures and behavior. Swaps this
package's hand-rolled connection dispatch and marker resolution for the
shared primitives in
modern_di.integrations,
shipped in
modern-di 2.28.0.
Fourth of 13 planned adapter conversions across the modern-di ecosystem
(after
modern-di-starlette 2.2.0,
modern-di-fastapi 2.10.0,
and
modern-di-litestar 2.13.0).
Internal refactors
_di_middlewarekeeps its owncan_prepare()handshake probe to
selectaiohttp_websocket_provideroraiohttp_request_provider— this
package is a documented outlier: both providers bindweb.Request(a
WebSocket is an upgraded HTTP request at aiohttp's middleware entry
point), sointegrations.classify_connection's isinstance-over-tuple
dispatch cannot distinguish them. Once the provider is picked,
integrations.bind(provider, request)now derives the scope/context
the middleware used to hand-write.bind()never returnsNone, so no
fallback branch is needed.- The child container's manual
try/finally: await child_container.close_async()is nowContainer's ownasync with—
entering an already-open container is a no-op; exiting closes it,
including on the exception path. _FromDI/_parse_inject_params/_resolve_di_paramsare gone.
FromDI = integrations.from_di;injectnow composes
integrations.parse_markers/integrations.resolve_markers.
Packaging
- Bumps the
modern-difloor to>=2.28.0,<3.
Downstream
No action needed — the public API (FromDI, inject, setup_di,
fetch_di_container, fetch_request_container,
aiohttp_request_provider/aiohttp_websocket_provider) is unchanged.
Upgrading only requires modern-di>=2.28.0.
Internals
- 100% line coverage;
ruff,tyclean across Python 3.10–3.14. - Built via
subagent-driven-development: 5 planned tasks, each with an
independent spec+quality review; a whole-branch review before merge.
2.1.0
modern-di-aiohttp 2.1.0 — adopt the modern-di 2.25 integration seams
Internal refactor, no behavior or API change: the integration now calls the
blessed Container seams instead of reaching into internals.
Internal refactors
container.add_providers(...)replaces theproviders_registryreach-in.
setup_dinow registers the connection providers via
container.add_providers(*_CONNECTION_PROVIDERS)instead of
container.providers_registry.add_providers(...).container.resolve_dependency(...)replaces the marker-dispatch
isinstancecheck._resolve_di_paramsnow delegates provider-or-type
dispatch toContainer.resolve_dependencyinstead of re-implementing the
isinstance(marker.dependency, providers.AbstractProvider)branch.
Packaging
- Bumps the
modern-difloor to>=2.25.0,<3(from>=2.21.0,<3), the
release that adds these seams
(modern-python/modern-di#283).
Downstream
No action needed beyond picking up the new floor — no public API changed.
Internals
- 100% line coverage;
ruff,ty, andeof-fixerclean across Python
3.10–3.14.
2.0.0
modern-di-aiohttp 2.0.0 — first release
First release of the aiohttp integration for modern-di. It wires a
modern-di container into an aiohttp
web.Application and resolves dependencies into handlers. The version starts
at 2.0.0 to track the modern-di 2.x ecosystem alongside the other official
integrations.
aiohttp has no dependency-injection system of its own, so this integration
follows modern-di's decorator path: middleware owns the per-connection
container lifecycle, and an @inject decorator with FromDI markers resolves
dependencies.
Feature
setup_di(app, container). Stashes the root container on the app
(web.AppKey("modern_di_container", Container), read back with
fetch_di_container(app)), registers the connection providers, reopens the
container onon_startup(so repeated startup/cleanup cycles work), closes
it onon_cleanup, and installs the DI middleware. Returns the container.- Per-connection child containers. Middleware detects a WebSocket upgrade
viaweb.WebSocketResponse().can_prepare(request).okand opens a
Scope.REQUESTchild container for each HTTP request or aScope.SESSION
child for each WebSocket connection, injecting the connection as context and
closing the child when the connection ends. A handler reads its child
container withfetch_request_container(request). Per-message work inside a
WebSocket handler can open a nestedScope.REQUESTchild of the SESSION
container. FromDI+@inject. Mark a handler parameter with
Annotated[T, FromDI(provider_or_type)]and decorate the handler with
@inject; the decorator resolves each marked parameter from the
connection's child container. A clearRuntimeErroris raised if@inject
runs withoutsetup_di.aiohttp_request_provider/aiohttp_websocket_provider. Connection
providers exposing theweb.Request: the former is registered by type at
Scope.REQUESTfor HTTP handlers; the latter is reference-only
(bound_type=None) atScope.SESSIONfor WebSocket handlers, injected via
FromDI(aiohttp_websocket_provider).
Packaging
- Requires
aiohttp>=3.9,<4andmodern-di>=2.21.0,<3; Python 3.10–3.14. - Ships
py.typed; zero runtime dependencies beyond aiohttp and modern-di.
Downstream
No action needed — this is a new package.
Internals
- 100% line coverage;
ruff,ty, andeof-fixerclean across Python
3.10–3.14. - Uses the portable planning convention (
planning/) with anarchitecture/
truth home; releases are tag-driven.