0
# Framework Integrations
1
2
Web framework integrations providing GraphQL endpoints for popular Python web frameworks with framework-specific features and middleware. These integrations handle HTTP requests, WebSocket connections, and provide seamless GraphQL endpoint implementation.
3
4
## Capabilities
5
6
### FastAPI Integration
7
8
GraphQL router integration for FastAPI applications with automatic OpenAPI documentation.
9
10
```python { .api }
11
class GraphQLRouter:
12
"""FastAPI router for GraphQL endpoints."""
13
14
def __init__(
15
self,
16
schema: Schema,
17
*,
18
path: str = "/graphql",
19
graphql_ide: str = "graphiql",
20
allow_queries_via_get: bool = False,
21
context_getter: Callable = None,
22
root_value_getter: Callable = None
23
):
24
"""
25
Initialize FastAPI GraphQL router.
26
27
Args:
28
schema: Strawberry GraphQL schema
29
path: GraphQL endpoint path
30
graphql_ide: GraphQL IDE to use ('graphiql', 'apollo-studio', None)
31
allow_queries_via_get: Allow GET requests for queries
32
context_getter: Function to build request context
33
root_value_getter: Function to provide root value
34
"""
35
36
class BaseContext:
37
"""Base context class for FastAPI integration."""
38
39
def __init__(self, request: Request, response: Response):
40
self.request = request
41
self.response = response
42
```
43
44
**Usage Example:**
45
46
```python
47
from fastapi import FastAPI, Depends, Request
48
from strawberry.fastapi import GraphQLRouter
49
50
app = FastAPI()
51
52
# Custom context
53
class MyContext(BaseContext):
54
def __init__(self, request: Request, response: Response):
55
super().__init__(request, response)
56
self.user = get_current_user(request)
57
58
async def get_context(
59
request: Request,
60
response: Response
61
) -> MyContext:
62
return MyContext(request, response)
63
64
# Create GraphQL router
65
graphql_app = GraphQLRouter(
66
schema,
67
context_getter=get_context,
68
graphql_ide="apollo-studio"
69
)
70
71
# Add to FastAPI app
72
app.include_router(graphql_app, prefix="/graphql")
73
74
# Access context in resolvers
75
@strawberry.type
76
class Query:
77
@strawberry.field
78
def current_user(self, info: strawberry.Info) -> Optional[User]:
79
return info.context.user
80
```
81
82
### ASGI Integration
83
84
Direct ASGI application for GraphQL with HTTP and WebSocket support.
85
86
```python { .api }
87
class GraphQL:
88
"""ASGI application for GraphQL endpoints."""
89
90
def __init__(
91
self,
92
schema: Schema,
93
*,
94
graphql_ide: str = "graphiql",
95
allow_queries_via_get: bool = False,
96
keep_alive: bool = False,
97
keep_alive_interval: float = 1,
98
subscription_protocols: List[str] = None,
99
connection_init_wait_timeout: float = 60,
100
context_getter: Callable = None,
101
root_value_getter: Callable = None
102
):
103
"""
104
Initialize ASGI GraphQL application.
105
106
Args:
107
schema: Strawberry GraphQL schema
108
graphql_ide: GraphQL IDE to serve
109
allow_queries_via_get: Allow GET requests for queries
110
keep_alive: Enable WebSocket keep-alive
111
keep_alive_interval: Keep-alive interval in seconds
112
subscription_protocols: Supported subscription protocols
113
connection_init_wait_timeout: WebSocket connection timeout
114
context_getter: Function to build request context
115
root_value_getter: Function to provide root value
116
"""
117
118
async def __call__(self, scope: dict, receive: Callable, send: Callable):
119
"""ASGI application callable."""
120
```
121
122
**Usage Example:**
123
124
```python
125
from strawberry.asgi import GraphQL
126
import uvicorn
127
128
# Create ASGI GraphQL app
129
app = GraphQL(
130
schema,
131
graphql_ide="graphiql",
132
allow_queries_via_get=True,
133
subscription_protocols=["graphql-transport-ws", "graphql-ws"]
134
)
135
136
# Custom context with ASGI
137
async def get_context(request):
138
return {
139
"user": await get_user_from_request(request),
140
"database": get_database_connection()
141
}
142
143
app_with_context = GraphQL(
144
schema,
145
context_getter=get_context
146
)
147
148
# Run with uvicorn
149
if __name__ == "__main__":
150
uvicorn.run(app, host="0.0.0.0", port=8000)
151
```
152
153
### AIOHTTP Integration
154
155
GraphQL view for AIOHTTP web applications.
156
157
```python { .api }
158
class GraphQLView:
159
"""AIOHTTP view for GraphQL endpoints."""
160
161
def __init__(
162
self,
163
schema: Schema,
164
*,
165
graphql_ide: str = "graphiql",
166
allow_queries_via_get: bool = False,
167
context_getter: Callable = None,
168
root_value_getter: Callable = None
169
):
170
"""
171
Initialize AIOHTTP GraphQL view.
172
173
Args:
174
schema: Strawberry GraphQL schema
175
graphql_ide: GraphQL IDE to serve
176
allow_queries_via_get: Allow GET requests
177
context_getter: Function to build request context
178
root_value_getter: Function to provide root value
179
"""
180
181
async def __call__(self, request: web.Request) -> web.Response:
182
"""Handle AIOHTTP request."""
183
```
184
185
**Usage Example:**
186
187
```python
188
from aiohttp import web
189
from strawberry.aiohttp import GraphQLView
190
191
async def create_app():
192
# Custom context for AIOHTTP
193
async def get_context(request):
194
return {
195
"request": request,
196
"user": await get_user_from_session(request)
197
}
198
199
# Create GraphQL view
200
view = GraphQLView(
201
schema=schema,
202
context_getter=get_context
203
)
204
205
# Setup AIOHTTP app
206
app = web.Application()
207
app.router.add_route("*", "/graphql", view)
208
209
return app
210
211
# Run application
212
if __name__ == "__main__":
213
app = create_app()
214
web.run_app(app, host="localhost", port=8080)
215
```
216
217
### Django Integration
218
219
Integration with Django web framework through external package.
220
221
```python { .api }
222
# Note: Requires strawberry-graphql-django package
223
from strawberry_django import auto
224
from strawberry_django.views import AsyncGraphQLView, GraphQLView
225
226
# Django model integration
227
@strawberry_django.type(models.User)
228
class User:
229
name: auto
230
email: auto
231
posts: List["Post"]
232
233
# Django views
234
class MyGraphQLView(GraphQLView):
235
schema = schema
236
graphql_ide = "graphiql"
237
```
238
239
**Usage Example:**
240
241
```python
242
# Django URLs
243
from django.urls import path
244
from strawberry.django.views import GraphQLView
245
246
urlpatterns = [
247
path("graphql/", GraphQLView.as_view(schema=schema)),
248
]
249
250
# Django settings integration
251
INSTALLED_APPS = [
252
# ... other apps
253
"strawberry.django",
254
]
255
256
# Custom Django context
257
class DjangoContext:
258
def __init__(self, request):
259
self.request = request
260
self.user = request.user if request.user.is_authenticated else None
261
262
def get_context(request):
263
return DjangoContext(request)
264
265
# Use with view
266
GraphQLView.as_view(
267
schema=schema,
268
context_getter=get_context
269
)
270
```
271
272
### Flask Integration
273
274
GraphQL view for Flask web applications.
275
276
```python { .api }
277
class GraphQLView:
278
"""Flask view for GraphQL endpoints."""
279
280
def __init__(
281
self,
282
schema: Schema,
283
*,
284
graphql_ide: str = "graphiql",
285
allow_queries_via_get: bool = False,
286
context_getter: Callable = None,
287
root_value_getter: Callable = None
288
):
289
"""
290
Initialize Flask GraphQL view.
291
292
Args:
293
schema: Strawberry GraphQL schema
294
graphql_ide: GraphQL IDE to serve
295
allow_queries_via_get: Allow GET requests
296
context_getter: Function to build request context
297
root_value_getter: Function to provide root value
298
"""
299
300
def __call__(self) -> Response:
301
"""Handle Flask request."""
302
```
303
304
**Usage Example:**
305
306
```python
307
from flask import Flask, g, request
308
from strawberry.flask import GraphQLView
309
310
app = Flask(__name__)
311
312
# Custom context for Flask
313
def get_context():
314
return {
315
"request": request,
316
"user": g.user if hasattr(g, "user") else None,
317
"db": get_database_connection()
318
}
319
320
# Create GraphQL view
321
view = GraphQLView(
322
schema=schema,
323
context_getter=get_context
324
)
325
326
# Add route
327
app.add_url_rule(
328
"/graphql",
329
view_func=view,
330
methods=["GET", "POST"]
331
)
332
333
# Middleware for user authentication
334
@app.before_request
335
def load_user():
336
token = request.headers.get("Authorization")
337
if token:
338
g.user = get_user_from_token(token)
339
```
340
341
### Starlette/Litestar Integration
342
343
Integration with Starlette and Litestar ASGI frameworks.
344
345
```python { .api }
346
# Litestar integration
347
class BaseContext:
348
"""Base context for Litestar integration."""
349
pass
350
351
HTTPContextType = TypeVar("HTTPContextType", bound=BaseContext)
352
WebSocketContextType = TypeVar("WebSocketContextType", bound=BaseContext)
353
354
def make_graphql_controller(
355
schema: Schema,
356
*,
357
path: str = "/graphql",
358
graphql_ide: str = "graphiql",
359
context_getter: Callable = None
360
) -> Type:
361
"""
362
Create Litestar controller for GraphQL.
363
364
Args:
365
schema: Strawberry GraphQL schema
366
path: GraphQL endpoint path
367
graphql_ide: GraphQL IDE to serve
368
context_getter: Function to build request context
369
370
Returns:
371
Litestar controller class
372
"""
373
```
374
375
**Usage Example:**
376
377
```python
378
from litestar import Litestar
379
from strawberry.litestar import make_graphql_controller
380
381
# Custom context
382
class MyContext:
383
def __init__(self, request, user=None):
384
self.request = request
385
self.user = user
386
387
def get_context(request) -> MyContext:
388
return MyContext(request, get_current_user(request))
389
390
# Create controller
391
GraphQLController = make_graphql_controller(
392
schema,
393
path="/graphql",
394
context_getter=get_context
395
)
396
397
# Create Litestar app
398
app = Litestar(
399
route_handlers=[GraphQLController],
400
debug=True
401
)
402
```
403
404
### Django Channels Integration
405
406
Integration with Django Channels for WebSocket subscriptions.
407
408
```python { .api }
409
class ChannelsConsumer:
410
"""Base Django Channels consumer."""
411
pass
412
413
class GraphQLHTTPConsumer(ChannelsConsumer):
414
"""HTTP consumer for GraphQL over Django Channels."""
415
416
def __init__(self, schema: Schema): ...
417
418
class GraphQLWSConsumer(ChannelsConsumer):
419
"""WebSocket consumer for GraphQL subscriptions."""
420
421
def __init__(self, schema: Schema): ...
422
423
class GraphQLProtocolTypeRouter:
424
"""Protocol type router for Django Channels."""
425
426
def __init__(
427
self,
428
schema: Schema,
429
*,
430
http_consumer: Type = GraphQLHTTPConsumer,
431
websocket_consumer: Type = GraphQLWSConsumer
432
): ...
433
```
434
435
**Usage Example:**
436
437
```python
438
from channels.routing import ProtocolTypeRouter, URLRouter
439
from channels.auth import AuthMiddlewareStack
440
from strawberry.channels import GraphQLProtocolTypeRouter
441
442
# Django Channels routing
443
application = ProtocolTypeRouter({
444
"http": URLRouter([
445
# HTTP GraphQL
446
path("graphql/", GraphQLHTTPConsumer.as_asgi(schema=schema)),
447
]),
448
"websocket": AuthMiddlewareStack(
449
URLRouter([
450
# WebSocket subscriptions
451
path("graphql/", GraphQLWSConsumer.as_asgi(schema=schema)),
452
])
453
)
454
})
455
456
# Or use the protocol router helper
457
application = GraphQLProtocolTypeRouter(schema)
458
```
459
460
### Sanic Integration
461
462
GraphQL view for Sanic web framework.
463
464
```python { .api }
465
class GraphQLView:
466
"""Sanic view for GraphQL endpoints."""
467
468
def __init__(
469
self,
470
schema: Schema,
471
*,
472
graphql_ide: str = "graphiql",
473
allow_queries_via_get: bool = False,
474
context_getter: Callable = None
475
): ...
476
477
async def __call__(self, request: SanicRequest) -> SanicResponse:
478
"""Handle Sanic request."""
479
```
480
481
**Usage Example:**
482
483
```python
484
from sanic import Sanic, response
485
from strawberry.sanic import GraphQLView
486
487
app = Sanic("GraphQL")
488
489
# Custom context
490
async def get_context(request):
491
return {
492
"request": request,
493
"user": await get_user_from_token(request.token)
494
}
495
496
# Create and add GraphQL view
497
view = GraphQLView(
498
schema=schema,
499
context_getter=get_context
500
)
501
502
app.add_route(view, "/graphql", methods=["GET", "POST"])
503
```
504
505
### Quart Integration
506
507
GraphQL view for Quart async web framework.
508
509
```python { .api }
510
class GraphQLView:
511
"""Quart view for GraphQL endpoints."""
512
513
def __init__(
514
self,
515
schema: Schema,
516
*,
517
graphql_ide: str = "graphiql",
518
allow_queries_via_get: bool = False,
519
context_getter: Callable = None
520
): ...
521
522
async def __call__(self) -> QuartResponse:
523
"""Handle Quart request."""
524
```
525
526
**Usage Example:**
527
528
```python
529
from quart import Quart, request
530
from strawberry.quart import GraphQLView
531
532
app = Quart(__name__)
533
534
async def get_context():
535
return {
536
"request": request,
537
"user": await get_current_user()
538
}
539
540
view = GraphQLView(
541
schema=schema,
542
context_getter=get_context
543
)
544
545
app.add_url_rule("/graphql", view_func=view, methods=["GET", "POST"])
546
```
547
548
### AWS Chalice Integration
549
550
GraphQL view for AWS Chalice serverless framework.
551
552
```python { .api }
553
class GraphQLView:
554
"""Chalice view for GraphQL endpoints."""
555
556
def __init__(
557
self,
558
schema: Schema,
559
*,
560
graphql_ide: str = None, # Usually disabled in serverless
561
context_getter: Callable = None
562
): ...
563
564
def __call__(self) -> ChaliceResponse:
565
"""Handle Chalice request."""
566
```
567
568
**Usage Example:**
569
570
```python
571
from chalice import Chalice
572
from strawberry.chalice import GraphQLView
573
574
app = Chalice(app_name="graphql-api")
575
576
def get_context():
577
return {
578
"current_request": app.current_request,
579
"user": get_user_from_jwt(app.current_request)
580
}
581
582
view = GraphQLView(
583
schema=schema,
584
context_getter=get_context
585
)
586
587
@app.route("/graphql", methods=["POST"])
588
def graphql():
589
return view()
590
```
591
592
## Common Integration Patterns
593
594
### Request Context Building
595
596
```python
597
# Common context pattern across frameworks
598
class GraphQLContext:
599
def __init__(
600
self,
601
request,
602
user=None,
603
database=None,
604
cache=None
605
):
606
self.request = request
607
self.user = user
608
self.database = database
609
self.cache = cache
610
611
async def build_context(request):
612
# Extract user from authentication
613
user = None
614
auth_header = request.headers.get("Authorization")
615
if auth_header:
616
user = await authenticate_user(auth_header)
617
618
# Setup database connection
619
database = await get_database_connection()
620
621
# Setup cache
622
cache = get_cache_client()
623
624
return GraphQLContext(
625
request=request,
626
user=user,
627
database=database,
628
cache=cache
629
)
630
```
631
632
### Error Handling Across Frameworks
633
634
```python
635
from strawberry.extensions import MaskErrors
636
637
# Production error masking
638
production_schema = strawberry.Schema(
639
query=Query,
640
extensions=[
641
MaskErrors() # Hide internal errors in production
642
]
643
)
644
645
# Custom error formatting
646
class CustomErrorFormatter:
647
def format_error(self, error):
648
return {
649
"message": error.message,
650
"code": getattr(error.original_error, "code", "INTERNAL_ERROR"),
651
"path": error.path
652
}
653
```
654
655
### CORS and Security Headers
656
657
```python
658
# Framework-specific CORS handling
659
# FastAPI
660
from fastapi.middleware.cors import CORSMiddleware
661
662
app.add_middleware(
663
CORSMiddleware,
664
allow_origins=["https://yourfrontend.com"],
665
allow_methods=["POST", "GET"],
666
allow_headers=["Content-Type", "Authorization"]
667
)
668
669
# Flask
670
from flask_cors import CORS
671
CORS(app, origins=["https://yourfrontend.com"])
672
673
# ASGI with middleware
674
from starlette.middleware.cors import CORSMiddleware
675
676
app = CORSMiddleware(
677
GraphQL(schema),
678
allow_origins=["https://yourfrontend.com"],
679
allow_methods=["POST", "GET"],
680
allow_headers=["Content-Type", "Authorization"]
681
)
682
```