0
# Framework Integrations
1
2
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.
3
4
## Capabilities
5
6
### Common Integration Pattern
7
8
All framework integrations follow a consistent pattern with setup and injection functions.
9
10
```python { .api }
11
def setup_dishka(container: Container | AsyncContainer, app: Any) -> None:
12
"""
13
Set up Dishka integration with a framework application.
14
15
Parameters:
16
- container: Dishka container (sync or async depending on framework)
17
- app: Framework application instance
18
19
Side Effects:
20
- Registers middleware/hooks for dependency injection
21
- Configures container lifecycle management
22
- Sets up error handling for dependency resolution
23
"""
24
25
def inject(func: Callable) -> Callable:
26
"""
27
Decorator for automatic dependency injection in framework handlers.
28
29
Parameters:
30
- func: Handler function with FromDishka annotations
31
32
Returns:
33
Wrapped function with dependencies automatically injected
34
35
Usage:
36
Functions decorated with @inject will have parameters marked with
37
FromDishka[Type] automatically resolved from the container.
38
"""
39
```
40
41
### FastAPI Integration
42
43
Comprehensive integration for FastAPI with custom routing and automatic dependency injection.
44
45
```python { .api }
46
from dishka.integrations.fastapi import setup_dishka, inject, FromDishka, DishkaRoute
47
48
def setup_dishka(
49
container: Container | AsyncContainer,
50
app: FastAPI,
51
*,
52
finalize_container: bool = True
53
) -> None:
54
"""
55
Set up Dishka integration with FastAPI.
56
57
Parameters:
58
- container: Dishka container
59
- app: FastAPI application instance
60
- finalize_container: Whether to close container on app shutdown
61
"""
62
63
class DishkaRoute(APIRoute):
64
"""Custom FastAPI route class with built-in dependency injection"""
65
66
def get_route_handler(self) -> Callable:
67
"""Override to inject dependencies automatically"""
68
69
# Re-exported for convenience
70
FromDishka = FromDishka
71
```
72
73
**Usage Example:**
74
75
```python
76
from fastapi import FastAPI, APIRouter
77
from dishka import make_async_container, Provider, Scope
78
from dishka.integrations.fastapi import setup_dishka, inject, FromDishka, DishkaRoute
79
80
# Set up dependencies
81
provider = Provider()
82
provider.provide(UserService, scope=Scope.REQUEST)
83
container = make_async_container(provider)
84
85
# Create FastAPI app
86
app = FastAPI()
87
setup_dishka(container, app)
88
89
# Using inject decorator
90
@app.get("/users/{user_id}")
91
@inject
92
async def get_user(
93
user_id: int, # From path parameter
94
service: FromDishka[UserService] # Injected dependency
95
) -> dict:
96
return await service.get_user(user_id)
97
98
# Using custom route class
99
router = APIRouter(route_class=DishkaRoute)
100
101
@router.get("/users")
102
async def list_users(service: FromDishka[UserService]) -> list:
103
return await service.list_users()
104
105
app.include_router(router)
106
```
107
108
### Flask Integration
109
110
Integration for Flask with request-scoped dependency injection and cleanup.
111
112
```python { .api }
113
from dishka.integrations.flask import setup_dishka, inject, FromDishka, FlaskProvider
114
115
def setup_dishka(container: Container, app: Flask) -> None:
116
"""
117
Set up Dishka integration with Flask.
118
119
Parameters:
120
- container: Dishka container (must be synchronous)
121
- app: Flask application instance
122
"""
123
124
class FlaskProvider(Provider):
125
"""Flask-specific provider with framework dependencies"""
126
127
request = from_context(Request, scope=Scope.REQUEST)
128
"""Flask request object available as dependency"""
129
130
# Re-exported for convenience
131
FromDishka = FromDishka
132
```
133
134
**Usage Example:**
135
136
```python
137
from flask import Flask
138
from dishka import make_container, Provider, Scope
139
from dishka.integrations.flask import setup_dishka, inject, FromDishka, FlaskProvider
140
141
# Set up dependencies
142
provider = Provider()
143
provider.provide(UserService, scope=Scope.REQUEST)
144
145
flask_provider = FlaskProvider()
146
147
container = make_container(provider, flask_provider)
148
149
# Create Flask app
150
app = Flask(__name__)
151
setup_dishka(container, app)
152
153
@app.route("/users/<int:user_id>")
154
@inject
155
def get_user(user_id: int, service: FromDishka[UserService]) -> dict:
156
return service.get_user(user_id)
157
158
@app.route("/current-request")
159
@inject
160
def get_request_info(request: FromDishka[Request]) -> dict:
161
return {"method": request.method, "path": request.path}
162
```
163
164
### AIOHttp Integration
165
166
Integration for AIOHttp with async middleware and dependency injection.
167
168
```python { .api }
169
from dishka.integrations.aiohttp import setup_dishka, inject, FromDishka, AioHttpProvider
170
171
def setup_dishka(container: AsyncContainer, app: Application) -> None:
172
"""
173
Set up Dishka integration with AIOHttp.
174
175
Parameters:
176
- container: Dishka async container
177
- app: AIOHttp Application instance
178
"""
179
180
class AioHttpProvider(Provider):
181
"""AIOHttp-specific provider with framework dependencies"""
182
183
request = from_context(Request, scope=Scope.REQUEST)
184
"""AIOHttp request object available as dependency"""
185
186
# Re-exported for convenience
187
FromDishka = FromDishka
188
```
189
190
**Usage Example:**
191
192
```python
193
from aiohttp import Application, web
194
from dishka import make_async_container, Provider, Scope
195
from dishka.integrations.aiohttp import setup_dishka, inject, FromDishka, AioHttpProvider
196
197
# Set up dependencies
198
provider = Provider()
199
provider.provide(UserService, scope=Scope.REQUEST)
200
201
aiohttp_provider = AioHttpProvider()
202
203
container = make_async_container(provider, aiohttp_provider)
204
205
# Create AIOHttp app
206
app = Application()
207
setup_dishka(container, app)
208
209
@inject
210
async def get_user(
211
request: FromDishka[web.Request],
212
service: FromDishka[UserService]
213
) -> web.Response:
214
user_id = int(request.match_info['user_id'])
215
user_data = await service.get_user(user_id)
216
return web.json_response(user_data)
217
218
app.router.add_get("/users/{user_id}", get_user)
219
```
220
221
### Starlette Integration
222
223
Integration for Starlette with middleware support and dependency injection.
224
225
```python { .api }
226
from dishka.integrations.starlette import setup_dishka, inject, FromDishka, DishkaMiddleware
227
228
def setup_dishka(container: AsyncContainer, app: Starlette) -> None:
229
"""
230
Set up Dishka integration with Starlette.
231
232
Parameters:
233
- container: Dishka async container
234
- app: Starlette application instance
235
"""
236
237
class DishkaMiddleware:
238
"""Starlette middleware for dependency injection"""
239
240
def __init__(self, app: ASGIApp, container: AsyncContainer): ...
241
async def __call__(self, scope: Scope, receive: Receive, send: Send): ...
242
243
# Re-exported for convenience
244
FromDishka = FromDishka
245
```
246
247
### Other Web Framework Integrations
248
249
Additional web framework integrations following similar patterns.
250
251
**Sanic Integration:**
252
253
```python { .api }
254
from dishka.integrations.sanic import setup_dishka, inject, FromDishka, SanicProvider
255
256
def setup_dishka(container: AsyncContainer, app: Sanic) -> None: ...
257
258
class SanicProvider(Provider):
259
request = from_context(Request, scope=Scope.REQUEST)
260
```
261
262
**Litestar Integration:**
263
264
```python { .api }
265
from dishka.integrations.litestar import setup_dishka, inject, FromDishka
266
267
def setup_dishka(container: AsyncContainer, app: Litestar) -> None: ...
268
```
269
270
### Task Queue Integrations
271
272
Integrations for task queue and job processing frameworks.
273
274
**Celery Integration:**
275
276
```python { .api }
277
from dishka.integrations.celery import setup_dishka, inject, FromDishka
278
279
def setup_dishka(container: Container, app: Celery) -> None:
280
"""
281
Set up Dishka integration with Celery.
282
283
Parameters:
284
- container: Dishka container
285
- app: Celery application instance
286
"""
287
```
288
289
**Usage Example:**
290
291
```python
292
from celery import Celery
293
from dishka import make_container, Provider, Scope
294
from dishka.integrations.celery import setup_dishka, inject, FromDishka
295
296
provider = Provider()
297
provider.provide(TaskProcessor, scope=Scope.REQUEST)
298
299
container = make_container(provider)
300
app = Celery('tasks')
301
setup_dishka(container, app)
302
303
@app.task
304
@inject
305
def process_task(task_data: dict, processor: FromDishka[TaskProcessor]) -> str:
306
return processor.process(task_data)
307
```
308
309
**TaskIQ Integration:**
310
311
```python { .api }
312
from dishka.integrations.taskiq import setup_dishka, inject, FromDishka
313
314
def setup_dishka(container: AsyncContainer, broker: AsyncBroker) -> None: ...
315
```
316
317
**ARQ Integration:**
318
319
```python { .api }
320
from dishka.integrations.arq import setup_dishka, inject, FromDishka
321
322
def setup_dishka(container: AsyncContainer, worker_settings: dict) -> None: ...
323
```
324
325
### Bot Framework Integrations
326
327
Integrations for Telegram bot frameworks.
328
329
**Aiogram Integration:**
330
331
```python { .api }
332
from dishka.integrations.aiogram import setup_dishka, inject, FromDishka
333
334
def setup_dishka(container: AsyncContainer, dispatcher: Dispatcher) -> None:
335
"""
336
Set up Dishka integration with Aiogram.
337
338
Parameters:
339
- container: Dishka async container
340
- dispatcher: Aiogram dispatcher instance
341
"""
342
```
343
344
**Usage Example:**
345
346
```python
347
from aiogram import Bot, Dispatcher
348
from dishka import make_async_container, Provider, Scope
349
from dishka.integrations.aiogram import setup_dishka, inject, FromDishka
350
351
provider = Provider()
352
provider.provide(BotService, scope=Scope.REQUEST)
353
354
container = make_async_container(provider)
355
bot = Bot(token="TOKEN")
356
dp = Dispatcher()
357
setup_dishka(container, dp)
358
359
@dp.message()
360
@inject
361
async def handle_message(
362
message: Message, # From aiogram
363
service: FromDishka[BotService] # Injected
364
) -> None:
365
await service.process_message(message)
366
```
367
368
**Telebot Integration:**
369
370
```python { .api }
371
from dishka.integrations.telebot import setup_dishka, inject, FromDishka
372
373
def setup_dishka(container: Container, bot: TeleBot) -> None: ...
374
```
375
376
### CLI Integration
377
378
Integration for Click command-line framework.
379
380
```python { .api }
381
from dishka.integrations.click import setup_dishka, inject, FromDishka
382
383
def setup_dishka(container: Container, app: click.Group) -> None:
384
"""
385
Set up Dishka integration with Click.
386
387
Parameters:
388
- container: Dishka container
389
- app: Click Group/Command instance
390
"""
391
```
392
393
**Usage Example:**
394
395
```python
396
import click
397
from dishka import make_container, Provider, Scope
398
from dishka.integrations.click import setup_dishka, inject, FromDishka
399
400
provider = Provider()
401
provider.provide(ConfigService, scope=Scope.APP)
402
403
container = make_container(provider)
404
405
@click.group()
406
def cli():
407
pass
408
409
setup_dishka(container, cli)
410
411
@cli.command()
412
@click.argument('filename')
413
@inject
414
def process_file(filename: str, config: FromDishka[ConfigService]) -> None:
415
"""Process a file with injected configuration service."""
416
processor = FileProcessor(config.get_settings())
417
processor.process(filename)
418
```
419
420
### gRPC Integration
421
422
Integration for gRPCio server applications.
423
424
```python { .api }
425
from dishka.integrations.grpcio import setup_dishka, inject, FromDishka
426
427
def setup_dishka(container: AsyncContainer, server: grpc.Server) -> None:
428
"""
429
Set up Dishka integration with gRPC server.
430
431
Parameters:
432
- container: Dishka async container
433
- server: gRPC server instance
434
"""
435
```
436
437
### Message Streaming Integration
438
439
Integration for FastStream message processing framework.
440
441
```python { .api }
442
from dishka.integrations.faststream import setup_dishka, inject, FromDishka
443
444
def setup_dishka(container: AsyncContainer, broker: FastStream) -> None:
445
"""
446
Set up Dishka integration with FastStream.
447
448
Parameters:
449
- container: Dishka async container
450
- broker: FastStream broker instance
451
"""
452
```
453
454
### Integration Error Handling
455
456
Common error handling patterns across integrations.
457
458
```python { .api }
459
class IntegrationError(DishkaError):
460
"""Base class for integration-related errors"""
461
462
class SetupError(IntegrationError):
463
"""Raised when integration setup fails"""
464
465
class InjectionError(IntegrationError):
466
"""Raised when dependency injection fails during request handling"""
467
```
468
469
### Custom Integration Pattern
470
471
Pattern for creating custom framework integrations.
472
473
**Basic Integration Structure:**
474
475
```python
476
from dishka import Container, AsyncContainer, FromDishka
477
from typing import Callable, Any
478
479
def setup_custom_framework(
480
container: Container | AsyncContainer,
481
app: Any
482
) -> None:
483
"""
484
1. Register middleware/hooks with framework
485
2. Set up container lifecycle management
486
3. Configure error handling
487
"""
488
# Implementation specific to framework
489
pass
490
491
def inject(func: Callable) -> Callable:
492
"""
493
1. Inspect function signature for FromDishka annotations
494
2. Extract dependencies from container during request
495
3. Call original function with injected dependencies
496
"""
497
# Implementation for dependency injection
498
pass
499
```