Easy dependency injection without wiring
Project description
Injection
Easy dependency injection for all, works with Python 3.8-3.12. Main features and advantages:
- support Python 3.8-3.12;
- works with FastAPI, Flask, Litestar and Django REST Framework;
- support dependency injection via
Annotated
inFastAPI
; - the code is fully typed and checked with mypy;
- no third-party dependencies;
- multiple containers;
- overriding dependencies for tests without wiring;
- 100% code coverage and very simple code;
- good documentation;
- intuitive and almost identical api with dependency-injector, which will allow you to easily migrate to injection (see migration from dependency injector);
Installation
pip install deps-injection
Using example
import sys
if sys.version_info >= (3, 9):
from typing import Annotated
else:
from typing import Annotated
from unittest.mock import Mock
import pytest
from fastapi import APIRouter, Depends, FastAPI
from fastapi.testclient import TestClient
from injection import DeclarativeContainer, Provide, inject, providers
class Settings:
redis_url: str = "redis://localhost"
redis_port: int = 6379
class Redis:
def __init__(self, *, url: str, port: int):
self.uri = url + ":" + str(port)
self.url = url
self.port = port
def get(self, key):
return key
class Container(DeclarativeContainer):
settings = providers.Singleton(Settings)
redis = providers.Singleton(
Redis,
port=settings.provided.redis_port,
url=settings.provided.redis_url,
)
router = APIRouter(prefix="/api")
def create_app():
app = FastAPI()
app.include_router(router)
return app
RedisDependency = Annotated[Redis, Depends(Provide[Container.redis])]
@router.get("/values")
@inject
def some_get_endpoint_handler(redis: RedisDependency):
value = redis.get(299)
return {"detail": value}
@router.post("/values")
@inject
async def some_get_async_endpoint_handler(redis: RedisDependency):
value = redis.get(399)
return {"detail": value}
###################### TESTING ######################
@pytest.fixture(scope="session")
def app():
return create_app()
@pytest.fixture(scope="session")
def container():
return Container.instance()
@pytest.fixture()
def test_client(app):
client = TestClient(app)
return client
def test_override_providers(test_client, container):
def mock_get_method(_):
return "mock_get_method"
mock_redis = Mock()
mock_redis.get = mock_get_method
providers_to_override = {"redis": mock_redis}
with container.override_providers(providers_to_override):
response = test_client.get("/api/values")
assert response.status_code == 200
body = response.json()
assert body["detail"] == "mock_get_method"
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
deps_injection-1.2.1.tar.gz
(10.3 kB
view details)
Built Distribution
File details
Details for the file deps_injection-1.2.1.tar.gz
.
File metadata
- Download URL: deps_injection-1.2.1.tar.gz
- Upload date:
- Size: 10.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 12bdc8c71b0efef8188c36cdd84721e518ac1066a0ea35d9b553ffb90234fb94 |
|
MD5 | c6a9b6fb7e512b54c4e226df03d4051d |
|
BLAKE2b-256 | 942d1f63d52787dadc519f64546aeb018fb2537304816323d222899c89ce2397 |
File details
Details for the file deps_injection-1.2.1-py3-none-any.whl
.
File metadata
- Download URL: deps_injection-1.2.1-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4ddc8236ea073c9327def46632ef3f6cbc7054189794dca3795235596f0a42f7 |
|
MD5 | 83eaba90c81a862e9cdb9fd3ba92b688 |
|
BLAKE2b-256 | b2222be9cb1fbef6b21ad57de0ff580437af9179f87c4a9bf8c51210a63eae28 |