Cute DI framework with scopes and agreeable API for Python dependency injection
—
Ready-to-use integrations for popular Python frameworks with automatic dependency injection setup and middleware configuration. These integrations handle the boilerplate of connecting Dishka to framework request lifecycles.
All framework integrations follow a consistent pattern with setup and injection functions.
def setup_dishka(container: Container | AsyncContainer, app: Any) -> None:
"""
Set up Dishka integration with a framework application.
Parameters:
- container: Dishka container (sync or async depending on framework)
- app: Framework application instance
Side Effects:
- Registers middleware/hooks for dependency injection
- Configures container lifecycle management
- Sets up error handling for dependency resolution
"""
def inject(func: Callable) -> Callable:
"""
Decorator for automatic dependency injection in framework handlers.
Parameters:
- func: Handler function with FromDishka annotations
Returns:
Wrapped function with dependencies automatically injected
Usage:
Functions decorated with @inject will have parameters marked with
FromDishka[Type] automatically resolved from the container.
"""Comprehensive integration for FastAPI with custom routing and automatic dependency injection.
from dishka.integrations.fastapi import setup_dishka, inject, FromDishka, DishkaRoute
def setup_dishka(
container: Container | AsyncContainer,
app: FastAPI,
*,
finalize_container: bool = True
) -> None:
"""
Set up Dishka integration with FastAPI.
Parameters:
- container: Dishka container
- app: FastAPI application instance
- finalize_container: Whether to close container on app shutdown
"""
class DishkaRoute(APIRoute):
"""Custom FastAPI route class with built-in dependency injection"""
def get_route_handler(self) -> Callable:
"""Override to inject dependencies automatically"""
# Re-exported for convenience
FromDishka = FromDishkaUsage Example:
from fastapi import FastAPI, APIRouter
from dishka import make_async_container, Provider, Scope
from dishka.integrations.fastapi import setup_dishka, inject, FromDishka, DishkaRoute
# Set up dependencies
provider = Provider()
provider.provide(UserService, scope=Scope.REQUEST)
container = make_async_container(provider)
# Create FastAPI app
app = FastAPI()
setup_dishka(container, app)
# Using inject decorator
@app.get("/users/{user_id}")
@inject
async def get_user(
user_id: int, # From path parameter
service: FromDishka[UserService] # Injected dependency
) -> dict:
return await service.get_user(user_id)
# Using custom route class
router = APIRouter(route_class=DishkaRoute)
@router.get("/users")
async def list_users(service: FromDishka[UserService]) -> list:
return await service.list_users()
app.include_router(router)Integration for Flask with request-scoped dependency injection and cleanup.
from dishka.integrations.flask import setup_dishka, inject, FromDishka, FlaskProvider
def setup_dishka(container: Container, app: Flask) -> None:
"""
Set up Dishka integration with Flask.
Parameters:
- container: Dishka container (must be synchronous)
- app: Flask application instance
"""
class FlaskProvider(Provider):
"""Flask-specific provider with framework dependencies"""
request = from_context(Request, scope=Scope.REQUEST)
"""Flask request object available as dependency"""
# Re-exported for convenience
FromDishka = FromDishkaUsage Example:
from flask import Flask
from dishka import make_container, Provider, Scope
from dishka.integrations.flask import setup_dishka, inject, FromDishka, FlaskProvider
# Set up dependencies
provider = Provider()
provider.provide(UserService, scope=Scope.REQUEST)
flask_provider = FlaskProvider()
container = make_container(provider, flask_provider)
# Create Flask app
app = Flask(__name__)
setup_dishka(container, app)
@app.route("/users/<int:user_id>")
@inject
def get_user(user_id: int, service: FromDishka[UserService]) -> dict:
return service.get_user(user_id)
@app.route("/current-request")
@inject
def get_request_info(request: FromDishka[Request]) -> dict:
return {"method": request.method, "path": request.path}Integration for AIOHttp with async middleware and dependency injection.
from dishka.integrations.aiohttp import setup_dishka, inject, FromDishka, AioHttpProvider
def setup_dishka(container: AsyncContainer, app: Application) -> None:
"""
Set up Dishka integration with AIOHttp.
Parameters:
- container: Dishka async container
- app: AIOHttp Application instance
"""
class AioHttpProvider(Provider):
"""AIOHttp-specific provider with framework dependencies"""
request = from_context(Request, scope=Scope.REQUEST)
"""AIOHttp request object available as dependency"""
# Re-exported for convenience
FromDishka = FromDishkaUsage Example:
from aiohttp import Application, web
from dishka import make_async_container, Provider, Scope
from dishka.integrations.aiohttp import setup_dishka, inject, FromDishka, AioHttpProvider
# Set up dependencies
provider = Provider()
provider.provide(UserService, scope=Scope.REQUEST)
aiohttp_provider = AioHttpProvider()
container = make_async_container(provider, aiohttp_provider)
# Create AIOHttp app
app = Application()
setup_dishka(container, app)
@inject
async def get_user(
request: FromDishka[web.Request],
service: FromDishka[UserService]
) -> web.Response:
user_id = int(request.match_info['user_id'])
user_data = await service.get_user(user_id)
return web.json_response(user_data)
app.router.add_get("/users/{user_id}", get_user)Integration for Starlette with middleware support and dependency injection.
from dishka.integrations.starlette import setup_dishka, inject, FromDishka, DishkaMiddleware
def setup_dishka(container: AsyncContainer, app: Starlette) -> None:
"""
Set up Dishka integration with Starlette.
Parameters:
- container: Dishka async container
- app: Starlette application instance
"""
class DishkaMiddleware:
"""Starlette middleware for dependency injection"""
def __init__(self, app: ASGIApp, container: AsyncContainer): ...
async def __call__(self, scope: Scope, receive: Receive, send: Send): ...
# Re-exported for convenience
FromDishka = FromDishkaAdditional web framework integrations following similar patterns.
Sanic Integration:
from dishka.integrations.sanic import setup_dishka, inject, FromDishka, SanicProvider
def setup_dishka(container: AsyncContainer, app: Sanic) -> None: ...
class SanicProvider(Provider):
request = from_context(Request, scope=Scope.REQUEST)Litestar Integration:
from dishka.integrations.litestar import setup_dishka, inject, FromDishka
def setup_dishka(container: AsyncContainer, app: Litestar) -> None: ...Integrations for task queue and job processing frameworks.
Celery Integration:
from dishka.integrations.celery import setup_dishka, inject, FromDishka
def setup_dishka(container: Container, app: Celery) -> None:
"""
Set up Dishka integration with Celery.
Parameters:
- container: Dishka container
- app: Celery application instance
"""Usage Example:
from celery import Celery
from dishka import make_container, Provider, Scope
from dishka.integrations.celery import setup_dishka, inject, FromDishka
provider = Provider()
provider.provide(TaskProcessor, scope=Scope.REQUEST)
container = make_container(provider)
app = Celery('tasks')
setup_dishka(container, app)
@app.task
@inject
def process_task(task_data: dict, processor: FromDishka[TaskProcessor]) -> str:
return processor.process(task_data)TaskIQ Integration:
from dishka.integrations.taskiq import setup_dishka, inject, FromDishka
def setup_dishka(container: AsyncContainer, broker: AsyncBroker) -> None: ...ARQ Integration:
from dishka.integrations.arq import setup_dishka, inject, FromDishka
def setup_dishka(container: AsyncContainer, worker_settings: dict) -> None: ...Integrations for Telegram bot frameworks.
Aiogram Integration:
from dishka.integrations.aiogram import setup_dishka, inject, FromDishka
def setup_dishka(container: AsyncContainer, dispatcher: Dispatcher) -> None:
"""
Set up Dishka integration with Aiogram.
Parameters:
- container: Dishka async container
- dispatcher: Aiogram dispatcher instance
"""Usage Example:
from aiogram import Bot, Dispatcher
from dishka import make_async_container, Provider, Scope
from dishka.integrations.aiogram import setup_dishka, inject, FromDishka
provider = Provider()
provider.provide(BotService, scope=Scope.REQUEST)
container = make_async_container(provider)
bot = Bot(token="TOKEN")
dp = Dispatcher()
setup_dishka(container, dp)
@dp.message()
@inject
async def handle_message(
message: Message, # From aiogram
service: FromDishka[BotService] # Injected
) -> None:
await service.process_message(message)Telebot Integration:
from dishka.integrations.telebot import setup_dishka, inject, FromDishka
def setup_dishka(container: Container, bot: TeleBot) -> None: ...Integration for Click command-line framework.
from dishka.integrations.click import setup_dishka, inject, FromDishka
def setup_dishka(container: Container, app: click.Group) -> None:
"""
Set up Dishka integration with Click.
Parameters:
- container: Dishka container
- app: Click Group/Command instance
"""Usage Example:
import click
from dishka import make_container, Provider, Scope
from dishka.integrations.click import setup_dishka, inject, FromDishka
provider = Provider()
provider.provide(ConfigService, scope=Scope.APP)
container = make_container(provider)
@click.group()
def cli():
pass
setup_dishka(container, cli)
@cli.command()
@click.argument('filename')
@inject
def process_file(filename: str, config: FromDishka[ConfigService]) -> None:
"""Process a file with injected configuration service."""
processor = FileProcessor(config.get_settings())
processor.process(filename)Integration for gRPCio server applications.
from dishka.integrations.grpcio import setup_dishka, inject, FromDishka
def setup_dishka(container: AsyncContainer, server: grpc.Server) -> None:
"""
Set up Dishka integration with gRPC server.
Parameters:
- container: Dishka async container
- server: gRPC server instance
"""Integration for FastStream message processing framework.
from dishka.integrations.faststream import setup_dishka, inject, FromDishka
def setup_dishka(container: AsyncContainer, broker: FastStream) -> None:
"""
Set up Dishka integration with FastStream.
Parameters:
- container: Dishka async container
- broker: FastStream broker instance
"""Common error handling patterns across integrations.
class IntegrationError(DishkaError):
"""Base class for integration-related errors"""
class SetupError(IntegrationError):
"""Raised when integration setup fails"""
class InjectionError(IntegrationError):
"""Raised when dependency injection fails during request handling"""Pattern for creating custom framework integrations.
Basic Integration Structure:
from dishka import Container, AsyncContainer, FromDishka
from typing import Callable, Any
def setup_custom_framework(
container: Container | AsyncContainer,
app: Any
) -> None:
"""
1. Register middleware/hooks with framework
2. Set up container lifecycle management
3. Configure error handling
"""
# Implementation specific to framework
pass
def inject(func: Callable) -> Callable:
"""
1. Inspect function signature for FromDishka annotations
2. Extract dependencies from container during request
3. Call original function with injected dependencies
"""
# Implementation for dependency injection
passInstall with Tessl CLI
npx tessl i tessl/pypi-dishka