Skip to content

modern-python/modern-di-aiohttp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

modern-di-aiohttp

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

Modern-DI integration for aiohttp.

Installation

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

Usage

aiohttp has no dependency-injection system of its own, so modern-di-aiohttp pairs an @inject decorator with inert FromDI markers. setup_di stores the container on the app, opens it on startup and closes it on cleanup, and installs middleware that builds a per-connection child container automatically; FromDI resolves a provider (or type) into a handler parameter.

import dataclasses
import typing

from aiohttp import web
from modern_di import Container, Group, Scope, providers
from modern_di_aiohttp import FromDI, inject, setup_di


@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 index(
    request: web.Request,
    user_service: typing.Annotated[UserService, FromDI(Dependencies.user_service)],
) -> web.Response:
    return web.json_response({"debug": user_service.settings.debug})


app = web.Application()
app.router.add_get("/", index)
setup_di(app, Container(groups=[Dependencies], validate=True))

An HTTP request opens a Scope.REQUEST child container; a WebSocket connection opens a Scope.SESSION one. The connection aiohttp.web.Request is resolvable within DI: HTTP handlers and REQUEST-scoped factories inject it by type via aiohttp_request_provider, while WebSocket handlers read it via FromDI(aiohttp_websocket_provider). For per-message work inside a WebSocket handler, open a nested Scope.REQUEST child of the session container fetched with fetch_request_container.

API

Symbol Description
setup_di(app, container) Stores the container on the app, wires on_startup/on_cleanup (reopen on startup, close on cleanup), registers the connection providers, and installs the per-connection middleware
inject(handler) Decorator that resolves every FromDI-marked parameter from the request's child container and passes them to the handler
FromDI(dependency) Inert Annotated marker resolved by @inject; accepts a provider or a type
fetch_di_container(app) Returns the app-scoped root container
fetch_request_container(request) Returns the per-connection child container the middleware built for this request
aiohttp_request_provider ContextProvider for the current aiohttp.web.Request (REQUEST scope)
aiohttp_websocket_provider ContextProvider for the connection aiohttp.web.Request at WebSocket SESSION scope

πŸ“¦ 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.

Packages

 
 
 

Contributors