AutoDI is a modern, type-friendly dependency injection container that simplifies dependency management in Python applications while keeping your code clean and maintainable.
- Type-Safe Resolution: Leverages type hints, including
NewType, for resolving dependencies. - Flexible Scopes: Manages dependency lifecycles with
APP(singleton) andREQUESTscopes. - Lifecycle Hooks: Automates resource management with
init_hookanddestroy_hook. - Full Async Support: Seamlessly handles
asyncproviders and lifecycle hooks. - Test-Friendly: Provides
override_providerfor easy mocking and test isolation. - Framework Integrations: Offers helpers for frameworks like FastAPI.
pip install git+https://github.com/C0dwiz/autodifrom autodi import Container, Scope
# 1. Define your components
class Database:
def query(self, sql: str) -> str:
return f"Executing: {sql}"
class UserService:
def __init__(self, db: Database):
self.db = db
# 2. Create and configure the container
container = Container()
container.register(Database, scope=Scope.APP) # Singleton
container.register(UserService, scope=Scope.REQUEST) # Per-request
# 3. Resolve dependencies
with container.enter_scope(Scope.REQUEST):
service = container.resolve(UserService)
print(service.db.query("SELECT * FROM users"))from fastapi import FastAPI, Depends
from autodi import Container, Scope
from autodi.extensions.fastapi import setup_dependency_injection
app = FastAPI()
container = Container()
# This middleware handles REQUEST scope creation and cleanup
setup_dependency_injection(app, container)
class AuthService:
def login(self, user: str) -> str:
return f"Welcome {user}!"
container.register(AuthService, scope=Scope.REQUEST)
@app.get("/login/{user}")
async def login(user: str, auth: AuthService = Depends(container.resolve_async)):
return {"message": auth.login(user)}Manage resources like database connections automatically.
class DatabaseConnection:
async def connect(self):
print("Connecting to DB...")
async def close(self):
print("Closing DB connection...")
container.register(
DatabaseConnection,
scope=Scope.REQUEST,
init_hook="connect",
destroy_hook="close",
)
# `connect` is called on resolve, `close` is called when the scope ends.
async with container.enter_scope_async(Scope.REQUEST):
db = await container.resolve_async(DatabaseConnection)Explore our comprehensive guides:
We welcome contributions! Please see our Contribution Guidelines.
MIT © 2023 AutoDI Team