Modern-DI integration for Typer.
uv add modern-di-typer # or: pip install modern-di-typerimport typing
import typer
import modern_di
from modern_di import Scope, providers, Group
from modern_di_typer import FromDI, inject, setup_di
class Dependencies(Group):
settings = providers.Factory(creator=lambda: {"debug": True})
service = providers.Factory(scope=Scope.REQUEST, creator=MyService, bound_type=None)
app = typer.Typer()
container = modern_di.Container(groups=[Dependencies])
setup_di(app, container)
@app.command()
@inject
def my_command(
name: typing.Annotated[str, typer.Argument()],
service: typing.Annotated[MyService, FromDI(Dependencies.service)],
) -> None:
service.run(name)
if __name__ == "__main__":
with container:
app()Scope.ACTION dependencies live below the per-command Scope.REQUEST container.
Open one with action_scope(ctx): each with block yields a fresh action-scoped
container (a child of the command's request container), so you can open as many as
you need within a single command — one per item in a batch, for example.
import typer
from modern_di import Scope, providers, Group
from modern_di_typer import FromDI, action_scope, inject
class Dependencies(Group):
job = providers.Factory(scope=Scope.ACTION, creator=MyJob, bound_type=None)
@app.command()
@inject
def my_command(ctx: typer.Context) -> None:
for job_name in job_names:
with action_scope(ctx) as action:
action.resolve_provider(Dependencies.job).run()setup_di(app, container)— register the container with a Typer appinject— decorator that resolvesFromDI-annotated parameters before the command runs; also exposestyper.Contextwithctx.obj["di_container"]for manual useFromDI(provider)— marker used inAnnotated[T, FromDI(...)]; accepts a provider instance or a typeaction_scope(ctx)— context manager yielding a freshScope.ACTIONcontainer (a child of the command's request container); open one per actionfetch_di_container(ctx)— returns the app-scoped container fromctx.obj
- semvertag — a CLI
auto-tagger for GitLab/GitHub that wires its settings, API providers, and
version-bump strategies through a
modern_dicontainer withmodern-di-typer. Seesemvertag/ioc.pyfor a real-worldsetup_di+Groupsetup.
📦 PyPI
📝 License
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.