modern-di integration for aiogram 3.x.
Full guide: aiogram integration docs
Usage example: examples/
Installation
uv add modern-di-aiogram # or: pip install modern-di-aiogram
Usage
aiogram has no dependency-injection system of its own, so modern-di-aiogram pairs an @inject decorator with inert FromDI markers (or auto_inject=True to skip the decorator entirely). By default setup_di opens the root container on dispatcher startup, closes it on shutdown, and installs an outer middleware that builds a per-update Scope.REQUEST child container automatically.
import typing
from aiogram import Dispatcher
from aiogram.types import Message
from modern_di import Container, Group, Scope, providers
from modern_di_aiogram import FromDI, inject, setup_di
class Settings:
def __init__(self) -> None:
self.greeting = "hello"
class AppGroup(Group):
settings = providers.Factory(Settings, scope=Scope.APP, cache=True)
dispatcher = Dispatcher()
container = Container(groups=[AppGroup])
setup_di(dispatcher, container)
container.validate() # optional fail-fast; must come after setup_di registers its providers
@dispatcher.message()
@inject
async def greet(
message: Message,
settings: typing.Annotated[Settings, FromDI(AppGroup.settings)],
) -> None:
await message.answer(f"{settings.greeting}, {message.from_user.first_name}")
Pass auto_inject=True to setup_di to wrap every handler already registered on the dispatcher, so individual handlers don't need @inject. Register handlers before startup for this to take effect. Sync handlers work with both @inject and auto_inject: aiogram runs them in a worker thread as usual, and their FromDI parameters resolve from the same per-update child container. The current aiogram.types.Update and the concrete event it carries (Message, CallbackQuery, and so on) are resolvable within DI via the pre-built aiogram_update_provider / aiogram_event_provider context providers. aiogram-dialog getters and callbacks are supported via modern_di_aiogram.dialog; see the docs.
Sharing a container
When one container serves several apps, for example a bot and a web API in the same process, exactly one owner should open and close it. Pass manage_lifespan=False so the dispatcher leaves the root container alone, and open it yourself around running the apps:
setup_di(dispatcher, container, manage_lifespan=False)
async with container:
await dispatcher.start_polling(bot)
Each update still gets its own Scope.REQUEST child container, closed when the update is handled. APP-scoped finalizers run once, when the async with block exits.
API
| Symbol | Description |
|---|---|
setup_di(dispatcher, container, *, auto_inject=False, manage_lifespan=True) |
Stores the container on the dispatcher, registers the update/event providers, wires dispatcher.startup/dispatcher.shutdown to open/close it, and installs the per-update middleware. With auto_inject=True, also wraps every handler already registered at startup. With manage_lifespan=False, never opens or closes the container; per-update child containers are still built and closed. Returns the container |
FromDI(dependency) |
Inert marker (used with @inject) that resolves a provider or type from the per-update child container |
inject(handler) |
Decorator for an aiogram handler, sync or async; resolves its FromDI-annotated parameters and returns a wrapper of the same kind. Not needed when setup_di(..., auto_inject=True) is used. Raises RuntimeError naming setup_di when an update reaches it without the middleware installed |
fetch_di_container(dispatcher) |
Returns the root Container stored on the dispatcher |
aiogram_update_provider |
ContextProvider for the current aiogram.types.Update (REQUEST scope) |
aiogram_event_provider |
ContextProvider for the current aiogram.types.TelegramObject (REQUEST scope): the concrete event unwrapped from the Update |
📦 PyPI
📝 License
Part of modern-python
Built on modern-di, a dependency-injection framework with an IoC container and scopes.
Browse the full list of templates and libraries in
modern-python; the org profile has the categorized index.
Metadata
Release files for modern-di-aiogram 4.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| modern_di_aiogram-4.2.0.tar.gz | 7.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| modern_di_aiogram-4.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.5 kB
Release files / modern_di_aiogram-4.2.0.tar.gz
| Download URL | modern_di_aiogram-4.2.0.tar.gz |
|---|---|
| Size | 7.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8349858e3104af25052c377a8ab312ee6f7b6cf9b40273b4096fa7278c5812ba
|
|
BLAKE2b-256 checksum How to use checksums |
1aaa9d2a5c946595b6c56f7be0f6597d28aa5e59bf554833b40ef727140665c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / modern_di_aiogram-4.2.0-py3-none-any.whl
| Download URL | modern_di_aiogram-4.2.0-py3-none-any.whl |
|---|---|
| Size | 7.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aef775028a1a1d5ae1d62775ca11b943ead57ee66319ce606377aaf3bea3e638
|
|
BLAKE2b-256 checksum How to use checksums |
5379e42280cd64b2dd5cb3c49ce9b89d5368305fdac03726ac3a46f81bac2d29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|