# Injection
![PyPI - Version](https://img.shields.io/pypi/v/deps-injection?label=pypi%20version&color=012111012)
![GitHub License](https://img.shields.io/github/license/nightblure/injection?color=012111012)
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/deps-injection)
[![Latest Release](https://github.com/nightblure/injection/actions/workflows/publish.yml/badge.svg)](https://github.com/nightblure/injection/actions/workflows/publish.yml)
[![Documentation Status](https://readthedocs.org/projects/injection/badge/?version=latest)](https://injection.readthedocs.io/en/latest/?badge=latest)
[![Tests And Linting](https://github.com/nightblure/injection/actions/workflows/ci.yml/badge.svg)](https://github.com/nightblure/injection/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/nightblure/injection/graph/badge.svg?token=2ZTFBlJqTb)](https://codecov.io/gh/nightblure/injection)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)
[![pdm-managed](https://img.shields.io/endpoint?url=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fpdm-project%2F.github%2Fbadge.json)](https://pdm-project.org)
[![Maintainability](https://api.codeclimate.com/v1/badges/1da49eb0b28eacae4624/maintainability)](https://codeclimate.com/github/nightblure/injection/maintainability)
![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/nightblure/injection/total?color=102255102&label=Total%20downloads)
![PyPI - Month Downloads](https://img.shields.io/pypi/dm/deps-injection?color=102255102&label=Month%20downloads)
![GitHub Repo stars](https://img.shields.io/github/stars/nightblure/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**;
* dependency injection via `Annotated` in FastAPI;
* **no third-party dependencies**;
* **multiple containers**;
* **overriding** dependencies for tests without wiring;
* **100%** code coverage and very simple code;
* 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
```
## Using example
```python3
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"
```
---
Raw data
{
"_id": null,
"home_page": null,
"name": "deps-injection",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "dependency, di, injection, injector",
"author": null,
"author_email": "Ivan Belyaev <vanobel159@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/e2/9a/1a4141ad2aedfce83f5de65c806376f28d04ec00af819ece1f85913a7403/deps_injection-1.1.0.tar.gz",
"platform": null,
"description": "# Injection\n\n![PyPI - Version](https://img.shields.io/pypi/v/deps-injection?label=pypi%20version&color=012111012)\n![GitHub License](https://img.shields.io/github/license/nightblure/injection?color=012111012)\n\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/deps-injection)\n\n[![Latest Release](https://github.com/nightblure/injection/actions/workflows/publish.yml/badge.svg)](https://github.com/nightblure/injection/actions/workflows/publish.yml)\n[![Documentation Status](https://readthedocs.org/projects/injection/badge/?version=latest)](https://injection.readthedocs.io/en/latest/?badge=latest)\n\n[![Tests And Linting](https://github.com/nightblure/injection/actions/workflows/ci.yml/badge.svg)](https://github.com/nightblure/injection/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/nightblure/injection/graph/badge.svg?token=2ZTFBlJqTb)](https://codecov.io/gh/nightblure/injection)\n\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n[![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)\n[![pdm-managed](https://img.shields.io/endpoint?url=https%3A%2F%2Fcdn.jsdelivr.net%2Fgh%2Fpdm-project%2F.github%2Fbadge.json)](https://pdm-project.org)\n\n[![Maintainability](https://api.codeclimate.com/v1/badges/1da49eb0b28eacae4624/maintainability)](https://codeclimate.com/github/nightblure/injection/maintainability)\n![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/nightblure/injection/total?color=102255102&label=Total%20downloads)\n\n![PyPI - Month Downloads](https://img.shields.io/pypi/dm/deps-injection?color=102255102&label=Month%20downloads)\n![GitHub Repo stars](https://img.shields.io/github/stars/nightblure/injection)\n\n---\n\nEasy dependency injection for all, works with Python 3.8-3.12. Main features and advantages:\n* support **Python 3.8-3.12**;\n* works with **FastAPI, Flask, Litestar** and **Django REST Framework**;\n* dependency injection via `Annotated` in FastAPI;\n* **no third-party dependencies**;\n* **multiple containers**;\n* **overriding** dependencies for tests without wiring;\n* **100%** code coverage and very simple code;\n* good [documentation](https://injection.readthedocs.io/latest/);\n* intuitive and almost identical api with [dependency-injector](https://github.com/ets-labs/python-dependency-injector),\nwhich will allow you to easily migrate to injection\n(see [migration from dependency injector](https://injection.readthedocs.io/latest/dev/migration-from-dependency-injector.html));\n\n---\n\n## Installation\n```shell\npip install deps-injection\n```\n\n## Using example\n\n```python3\nimport sys\n\nif sys.version_info >= (3, 9):\n from typing import Annotated\nelse:\n from typing import Annotated\nfrom unittest.mock import Mock\n\nimport pytest\nfrom fastapi import APIRouter, Depends, FastAPI\nfrom fastapi.testclient import TestClient\nfrom injection import DeclarativeContainer, Provide, inject, providers\n\n\nclass Settings:\n redis_url: str = \"redis://localhost\"\n redis_port: int = 6379\n\n\nclass Redis:\n def __init__(self, *, url: str, port: int):\n self.uri = url + \":\" + str(port)\n self.url = url\n self.port = port\n\n def get(self, key):\n return key\n\n\nclass Container(DeclarativeContainer):\n settings = providers.Singleton(Settings)\n redis = providers.Singleton(\n Redis,\n port=settings.provided.redis_port,\n url=settings.provided.redis_url,\n )\n\n\nrouter = APIRouter(prefix=\"/api\")\n\n\ndef create_app():\n app = FastAPI()\n app.include_router(router)\n return app\n\n\nRedisDependency = Annotated[Redis, Depends(Provide[Container.redis])]\n\n\n@router.get(\"/values\")\n@inject\ndef some_get_endpoint_handler(redis: RedisDependency):\n value = redis.get(299)\n return {\"detail\": value}\n\n\n@router.post(\"/values\")\n@inject\nasync def some_get_async_endpoint_handler(redis: RedisDependency):\n value = redis.get(399)\n return {\"detail\": value}\n\n\n###################### TESTING ######################\n@pytest.fixture(scope=\"session\")\ndef app():\n return create_app()\n\n\n@pytest.fixture(scope=\"session\")\ndef container():\n return Container.instance()\n\n\n@pytest.fixture()\ndef test_client(app):\n client = TestClient(app)\n return client\n\n\ndef test_override_providers(test_client, container):\n def mock_get_method(_):\n return \"mock_get_method\"\n\n mock_redis = Mock()\n mock_redis.get = mock_get_method\n\n providers_to_override = {\"redis\": mock_redis}\n\n with container.override_providers(providers_to_override):\n response = test_client.get(\"/api/values\")\n\n assert response.status_code == 200\n body = response.json()\n assert body[\"detail\"] == \"mock_get_method\"\n\n```\n\n---\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Easy dependency injection",
"version": "1.1.0",
"project_urls": {
"Changelog": "https://github.com/nightblure/injection/releases",
"Documentation": "https://injection.readthedocs.io/latest/",
"Homepage": "https://pypi.org/project/deps-injection/",
"Issues": "https://github.com/nightblure/injection/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc",
"Repository": "https://github.com/nightblure/injection.git"
},
"split_keywords": [
"dependency",
" di",
" injection",
" injector"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fc0ea49085c7ac1e88dc79433e879426e45be821997504663b2f34546a5b30f1",
"md5": "55461b14db57f2719746e432683665a4",
"sha256": "07a8ce0dca98c82959d5a0b2fa9925cb3df590da2a9fd82ec2adfaec64cdc446"
},
"downloads": -1,
"filename": "deps_injection-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "55461b14db57f2719746e432683665a4",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 12148,
"upload_time": "2024-08-03T19:13:51",
"upload_time_iso_8601": "2024-08-03T19:13:51.133060Z",
"url": "https://files.pythonhosted.org/packages/fc/0e/a49085c7ac1e88dc79433e879426e45be821997504663b2f34546a5b30f1/deps_injection-1.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e29a1a4141ad2aedfce83f5de65c806376f28d04ec00af819ece1f85913a7403",
"md5": "3666a255e5e20656e86922dac2ec5498",
"sha256": "0730400025be473ce59ec374f68041289623d8531d2a847bb425062a3af482f1"
},
"downloads": -1,
"filename": "deps_injection-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "3666a255e5e20656e86922dac2ec5498",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 9786,
"upload_time": "2024-08-03T19:13:52",
"upload_time_iso_8601": "2024-08-03T19:13:52.476828Z",
"url": "https://files.pythonhosted.org/packages/e2/9a/1a4141ad2aedfce83f5de65c806376f28d04ec00af819ece1f85913a7403/deps_injection-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-03 19:13:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "nightblure",
"github_project": "injection",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "deps-injection"
}