Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| [modern-di-fastapi](https://github.com/modern-python/modern-di-fastapi) | [![Supported versions](https://img.shields.io/pypi/pyversions/modern-di-fastapi.svg)](https://pypi.python.org/pypi/modern-di-fastapi) [![downloads](https://img.shields.io/pypi/dm/modern-di-fastapi.svg)](https://pypistats.org/packages/modern-di-fastapi) |
| [modern-di-faststream ](https://github.com/modern-python/modern-di-faststream) | [![Supported versions](https://img.shields.io/pypi/pyversions/modern-di-faststream.svg)](https://pypi.python.org/pypi/modern-di-faststream) [![downloads](https://img.shields.io/pypi/dm/modern-di-faststream.svg)](https://pypistats.org/packages/modern-di-faststream) |
| [modern-di-litestar ](https://github.com/modern-python/modern-di-litestar) | [![Supported versions](https://img.shields.io/pypi/pyversions/modern-di-litestar.svg)](https://pypi.python.org/pypi/modern-di-litestar) [![downloads](https://img.shields.io/pypi/dm/modern-di-litestar.svg)](https://pypistats.org/packages/modern-di-litestar) |
| [modern-di-typer](https://github.com/modern-python/modern-di-typer) | [![Supported versions](https://img.shields.io/pypi/pyversions/modern-di-typer.svg)](https://pypi.python.org/pypi/modern-di-typer) [![downloads](https://img.shields.io/pypi/dm/modern-di-typer.svg)](https://pypistats.org/packages/modern-di-typer) |

`modern-di` is a python dependency injection framework which supports the following:

Expand All @@ -16,7 +17,7 @@
- Scopes and context management
- Python 3.10+ support
- Fully typed and tested
- Integrations with `FastAPI`, `FastStream` and `LiteStar`
- Integrations with `FastAPI`, `FastStream`,`LiteStar` and `Typer`

Usage examples:

Expand Down
108 changes: 108 additions & 0 deletions docs/integrations/typer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Usage with `Typer`

## How to use

1. Install `modern-di-typer`:

=== "uv"

```bash
uv add modern-di-typer
```

=== "pip"

```bash
pip install modern-di-typer
```

=== "poetry"

```bash
poetry add modern-di-typer
```

2. Apply this code example to your application:

```python
import datetime
import typing

import modern_di
import modern_di_typer
import typer
from modern_di import Container, Group, Scope, providers


app = typer.Typer()


def create_singleton() -> datetime.datetime:
return datetime.datetime.now(tz=datetime.timezone.utc)


class AppGroup(Group):
singleton = providers.Factory(
scope=Scope.APP,
creator=create_singleton,
cache_settings=providers.CacheSettings()
)


ALL_GROUPS = [AppGroup]

container = Container(groups=ALL_GROUPS)
modern_di_typer.setup_di(app, container)


@app.command()
@modern_di_typer.inject
def my_command(
instance: typing.Annotated[
datetime.datetime,
modern_di_typer.FromDI(datetime.datetime), # Resolve by type instead of provider
],
) -> None:
typer.echo(instance)


if __name__ == "__main__":
with container:
app()
```

## Action scope

To resolve `Scope.ACTION` dependencies, inject `modern_di.Container` — `@inject` supplies the
`REQUEST`-scoped container it creates per invocation. Call `build_child_container()` on it to enter
`ACTION` scope:

```python
import modern_di
import modern_di_typer
import typing
from modern_di import Group, Scope, providers


class AppGroup(Group):
job = providers.Factory(scope=Scope.ACTION, creator=..., bound_type=None)


@app.command()
@modern_di_typer.inject
def run_job(
container: typing.Annotated[modern_di.Container, modern_di_typer.FromDI(modern_di.Container)],
) -> None:
with container.build_child_container() as action_container:
job = action_container.resolve_provider(AppGroup.job)
job.run()
```

## API

| Symbol | Description |
|---|---|
| `setup_di(app, container)` | Register the app-scoped container with a Typer app |
| `@inject` | Decorator that resolves `FromDI`-annotated parameters before the command runs |
| `FromDI(provider_or_type)` | Marker for `Annotated[T, FromDI(...)]`; accepts a provider instance or a plain type |
| `fetch_di_container(ctx)` | Returns the app-scoped container from `ctx.obj` |
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ nav:
- FastAPI: integrations/fastapi.md
- FastStream: integrations/faststream.md
- Litestar: integrations/litestar.md
- Typer: integrations/typer.md
- Testing:
- Fixtures: testing/fixtures.md
- Troubleshooting:
Expand Down
Loading