Skip to main content

Easy dependency injection without wiring

Project description

Injection

PyPI - Version GitHub License

PyPI - Python Version

Latest Release Documentation Status

Tests And Linting codecov

Ruff Hatch project uv MyPy Strict

Maintainability GitHub Downloads (all assets, all releases)

PyPI - Month Downloads GitHub Repo stars


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, Litestar, Flask and Django REST Framework;
  • support dependency injection via Annotated in FastAPI;
  • the code is fully typed and checked with mypy;
  • no third-party dependencies;
  • support async injections;
  • no wiring;
  • the life cycle of objects (scope) is implemented by providers;
  • overriding dependencies for testing;
  • 100% code coverage;
  • 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

Compatibility between web frameworks and injection features

Framework Dependency injection with @inject Overriding providers Dependency injection with @autoinject
FastAPI
Flask
Django REST Framework
Litestar

Using example with FastAPI and SQLAlchemy

from contextlib import contextmanager
from random import Random
from typing import Annotated, Any, Callable, Dict, Iterator

import pytest
from fastapi import Depends, FastAPI
from sqlalchemy import create_engine, text
from sqlalchemy.orm import Session, sessionmaker
from starlette.testclient import TestClient

from 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_session

    def get_some_data(self, num: int) -> int:
        stmt = text("SELECT :num").bindparams(num=num)
        data: int = self.db_session.execute(stmt).scalar_one()
        return data


class 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 client


def 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

Project details


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.6.2.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

deps_injection-1.6.2-py3-none-any.whl (16.1 kB view details)

Uploaded Python 3

File details

Details for the file deps_injection-1.6.2.tar.gz.

File metadata

  • Download URL: deps_injection-1.6.2.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for deps_injection-1.6.2.tar.gz
Algorithm Hash digest
SHA256 b1fcedd12f463a03b18acd868c8429a2ba7cb7f9db797cdfb9556c7b39756f4e
MD5 85afe2bbdde9a81531bdd1c7d9ef39a9
BLAKE2b-256 e4613d3f20d0af3bd250ad6831efc477566ff73e9e80c7adc0aae53b0a2f05ac

See more details on using hashes here.

Provenance

The following attestation bundles were made for deps_injection-1.6.2.tar.gz:

Publisher: publish.yml on nightblure/injection

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deps_injection-1.6.2-py3-none-any.whl.

File metadata

  • Download URL: deps_injection-1.6.2-py3-none-any.whl
  • Upload date:
  • Size: 16.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for deps_injection-1.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4f3f47b82771b990439e9e91df062b19bb2bca12f7942bc1e4c32b0d0ed3dc76
MD5 ca1da06c132d55fb47ada502f610e3b8
BLAKE2b-256 02ea6230448baa9f3bea02c0353e07bc022bf7c747076cea34d2b754aa71c4df

See more details on using hashes here.

Provenance

The following attestation bundles were made for deps_injection-1.6.2-py3-none-any.whl:

Publisher: publish.yml on nightblure/injection

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page