Dependency injection framework for Python
npx @tessl/cli install tessl/pypi-dependency-injector@4.48.0A comprehensive dependency injection framework for Python that enables developers to implement the dependency injection principle effectively. It provides various provider types for dependency assembly, supports provider overriding for testing, reads configuration from multiple sources, offers resource management capabilities, and includes framework integration through dependency wiring.
pip install dependency-injectorfrom dependency_injector import containers, providersCommon for dependency wiring:
from dependency_injector.wiring import Provide, injectResource management:
from dependency_injector import resourcesfrom dependency_injector import containers, providers
from dependency_injector.wiring import Provide, inject
# Define services
class Database:
def __init__(self, connection_string: str):
self.connection_string = connection_string
def query(self, sql: str):
return f"Executing: {sql}"
class UserService:
def __init__(self, database: Database):
self.database = database
def get_user(self, user_id: int):
return self.database.query(f"SELECT * FROM users WHERE id = {user_id}")
# Create container with providers
class Container(containers.DeclarativeContainer):
# Configuration provider
config = providers.Configuration()
# Singleton database connection
database = providers.Singleton(
Database,
config.database.connection_string,
)
# Factory for user service instances
user_service = providers.Factory(
UserService,
database=database,
)
# Configure and wire dependencies
container = Container()
container.config.database.connection_string.from_value("postgresql://localhost/mydb")
container.wire(modules=[__name__])
# Use dependency injection
@inject
def main(user_service: UserService = Provide[Container.user_service]):
user = user_service.get_user(123)
print(user)
if __name__ == "__main__":
main()The dependency injector framework is built around several key components:
This design enables clean separation of concerns, testable code through provider overriding, and flexible dependency management across different environments and frameworks.
Complete set of provider types for dependency creation and management including factories, singletons, callables, configurations, resources, collections, and dependency placeholders.
class Provider:
def __call__(self, *args, **kwargs): ...
def override(self, provider): ...
def reset_override(self): ...
class Factory(Provider):
def __init__(self, provides, *args, **kwargs): ...
class Singleton(Provider):
def __init__(self, provides, *args, **kwargs): ...
def reset(self): ...
class Configuration(Provider):
def __init__(self, name="config"): ...
def from_yaml(self, filepath): ...
def from_env(self, name, default=None): ...Container classes for organizing providers with support for declarative and dynamic configuration, provider overriding, dependency wiring, and resource lifecycle management.
class Container:
def wire(self, modules=None, packages=None): ...
def unwire(self): ...
def override(self, overriding): ...
def reset_singletons(self): ...
class DeclarativeContainer(Container): ...
class DynamicContainer(Container):
def set_providers(self, **providers): ...Decorators and markers for automatic dependency injection into functions, methods, and class attributes with support for synchronous and asynchronous code.
def inject(fn): ...
def wire(container, modules=None, packages=None): ...
class Provide:
def __class_getitem__(cls, provider): ...
class Provider:
def __class_getitem__(cls, provider): ...Base classes and providers for managing resource lifecycles with automatic initialization and cleanup support for both synchronous and asynchronous resources.
class Resource:
def init(self, *args, **kwargs): ...
def shutdown(self, resource): ...
class AsyncResource:
async def init(self, *args, **kwargs): ...
async def shutdown(self, resource): ...Utilities for creating containers from configuration schemas with support for dynamic provider creation and dependency graph construction.
class SchemaProcessorV1:
def __init__(self, schema): ...
def process(self): ...
def get_providers(self): ...Integration modules for popular Python web frameworks, providing specialized providers and utilities for framework-specific dependency injection.
# Flask extension (deprecated since v4.0.0)
from dependency_injector.ext.flask import Application, Extension, View, ClassBasedView
# Aiohttp extension (deprecated since v4.0.0)
from dependency_injector.ext.aiohttp import Application, Extension, Middleware, View, ClassBasedView
# Starlette extension
from dependency_injector.ext.starlette import LifespanNote: Flask and Aiohttp extensions are deprecated since version 4.0.0. Use the core dependency injection features directly with these frameworks instead.
The framework defines specific exceptions for dependency injection errors:
class Error(Exception):
"""Base exception for dependency injection errors."""
class NoSuchProviderError(Error, AttributeError):
"""Raised when accessing non-existent provider attributes."""
class NonCopyableArgumentError(Error):
"""Raised when trying to copy providers with non-copyable arguments."""
@property
def index(self): ...
@property
def keyword(self): ...
@property
def provider(self): ...These exceptions help identify configuration and runtime issues in dependency injection setups. The framework provides specific error types to help developers quickly identify and resolve dependency injection problems.