https://github.com/nightblure/injection
Dependency injection, works with FastAPI, Litestar, Django, Flask (Python 3.8-3.13). Light replacement with new features for dependency-injector
https://github.com/nightblure/injection
dependency-injection dependency-injection-container dependency-injection-framework dependency-injector di di-container injection injector ioc-container singleton
Last synced: about 1 month ago
JSON representation
Dependency injection, works with FastAPI, Litestar, Django, Flask (Python 3.8-3.13). Light replacement with new features for dependency-injector
- Host: GitHub
- URL: https://github.com/nightblure/injection
- Owner: nightblure
- License: mit
- Created: 2024-07-26T12:32:23.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-02-07T07:44:58.000Z (2 months ago)
- Last Synced: 2025-02-07T07:46:19.081Z (2 months ago)
- Topics: dependency-injection, dependency-injection-container, dependency-injection-framework, dependency-injector, di, di-container, injection, injector, ioc-container, singleton
- Language: Python
- Homepage: https://injection.readthedocs.io/latest/
- Size: 437 KB
- Stars: 15
- Watchers: 2
- Forks: 1
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-dependency-injection-in-python - injection - replacement for [python-dependency-injector](https://github.com/ets-labs/python-dependency-injector) that works with Python 3.8-3.12 and works with FastAPI, DRF, Flask and Litestar [🐍, MIT License]. (Software / DI Frameworks / Containers)
README
# Injection


[](https://github.com/nightblure/injection/actions/workflows/publish.yml)
[](https://injection.readthedocs.io/en/latest/?badge=latest)[](https://github.com/nightblure/injection/actions/workflows/ci.yml)
[](https://codecov.io/gh/nightblure/injection)[](https://github.com/astral-sh/ruff)
[](https://github.com/pypa/hatch)
[](https://github.com/astral-sh/uv)
[](https://mypy.readthedocs.io/en/stable/getting_started.html#strict-mode-and-configuration)

---
Easy dependency injection for all, works with Python 3.8-3.13. Main features and advantages:
* support **Python 3.8-3.13**;
* works with **FastAPI, **Litestar**, Flask** and **Django REST Framework**;
* support **dependency** **injection** via `Annotated` in `FastAPI`;
* support **async injections**;
* support [**auto injection by types**](https://injection.readthedocs.io/latest/injection/auto_injection.html);
* [**resources**](https://injection.readthedocs.io/latest/providers/resource.html) with **function scope**;
* no **wiring**;
* **overriding** dependencies for testing;
* **100%** code coverage;
* the code is fully **typed** and checked with [mypy](https://github.com/python/mypy);
* good [documentation](https://injection.readthedocs.io/latest/);
* intuitive and almost identical api with [dependency-injector](https://github.com/ets-labs/python-dependency-injector),
which will allow you to easily migrate to injection
(see [migration from dependency injector](https://injection.readthedocs.io/latest/dev/migration-from-dependency-injector.html));---
## Installation
```shell
pip install deps-injection
```## Compatibility between web frameworks and injection features
| Framework | Dependency injection with @inject | Overriding providers | Dependency injection with @autoinject |
|--------------------------------------------------------------------------|:---------------------------------:|:--------------------:|:-------------------------------------------:|
| [FastAPI](https://github.com/fastapi/fastapi) | ✅ | ✅ | ➖ |
| [Flask](https://github.com/pallets/flask) | ✅ | ✅ | ✅ |
| [Django REST Framework](https://github.com/encode/django-rest-framework) | ✅ | ✅ | ✅ |
| [Litestar](https://github.com/litestar-org/litestar) | ✅ | ✅ | ➖ | ➖ |## Quickstart with FastAPI, SQLAlchemy and pytest
```python3
from contextlib import contextmanager
from random import Random
from typing import Annotated, Any, Callable, Dict, Iteratorimport pytest
from fastapi import Depends, FastAPI
from sqlalchemy import create_engine, text
from sqlalchemy.orm import Session, sessionmaker
from starlette.testclient import TestClientfrom injection import DeclarativeContainer, Provide, inject, providers
@contextmanager
def db_session_resource(session_factory: Callable[..., Session]) -> Iterator[Session]:
session = session_factory()
try:
yield session
except Exception:
session.rollback()
finally:
session.close()class SomeDAO:
def __init__(self, db_session: Session) -> None:
self.db_session = db_sessiondef get_some_data(self, num: int) -> int:
stmt = text("SELECT :num").bindparams(num=num)
data: int = self.db_session.execute(stmt).scalar_one()
return dataclass DIContainer(DeclarativeContainer):
db_engine = providers.Singleton(
create_engine,
url="sqlite:///db.db",
pool_size=20,
max_overflow=0,
pool_pre_ping=False,
)session_factory = providers.Singleton(
sessionmaker,
db_engine.cast,
autoflush=False,
autocommit=False,
)db_session = providers.Resource(
db_session_resource,
session_factory=session_factory.cast,
function_scope=True,
)some_dao = providers.Factory(SomeDAO, db_session=db_session.cast)
SomeDAODependency = Annotated[SomeDAO, Depends(Provide[DIContainer.some_dao])]
app = FastAPI()
@app.get("/values/{value}")
@inject
async def sqla_resource_handler_async(
value: int,
some_dao: SomeDAODependency,
) -> Dict[str, Any]:
value = some_dao.get_some_data(num=value)
return {"detail": value}@pytest.fixture(scope="session")
def test_client() -> TestClient:
client = TestClient(app)
return clientdef test_sqla_resource(test_client: TestClient) -> None:
rnd = Random()
random_int = rnd.randint(-(10**6), 10**6)response = test_client.get(f"/values/{random_int}")
assert response.status_code == 200
assert not DIContainer.db_session.initialized
body = response.json()
assert body["detail"] == random_int
```