A library for creating GraphQL APIs using dataclasses and type annotations with extensive framework integration support.
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.
GraphQL router integration for FastAPI applications with automatic OpenAPI documentation.
class GraphQLRouter:
"""FastAPI router for GraphQL endpoints."""
def __init__(
self,
schema: Schema,
*,
path: str = "/graphql",
graphql_ide: str = "graphiql",
allow_queries_via_get: bool = False,
context_getter: Callable = None,
root_value_getter: Callable = None
):
"""
Initialize FastAPI GraphQL router.
Args:
schema: Strawberry GraphQL schema
path: GraphQL endpoint path
graphql_ide: GraphQL IDE to use ('graphiql', 'apollo-studio', None)
allow_queries_via_get: Allow GET requests for queries
context_getter: Function to build request context
root_value_getter: Function to provide root value
"""
class BaseContext:
"""Base context class for FastAPI integration."""
def __init__(self, request: Request, response: Response):
self.request = request
self.response = responseUsage Example:
from fastapi import FastAPI, Depends, Request
from strawberry.fastapi import GraphQLRouter
app = FastAPI()
# Custom context
class MyContext(BaseContext):
def __init__(self, request: Request, response: Response):
super().__init__(request, response)
self.user = get_current_user(request)
async def get_context(
request: Request,
response: Response
) -> MyContext:
return MyContext(request, response)
# Create GraphQL router
graphql_app = GraphQLRouter(
schema,
context_getter=get_context,
graphql_ide="apollo-studio"
)
# Add to FastAPI app
app.include_router(graphql_app, prefix="/graphql")
# Access context in resolvers
@strawberry.type
class Query:
@strawberry.field
def current_user(self, info: strawberry.Info) -> Optional[User]:
return info.context.userDirect ASGI application for GraphQL with HTTP and WebSocket support.
class GraphQL:
"""ASGI application for GraphQL endpoints."""
def __init__(
self,
schema: Schema,
*,
graphql_ide: str = "graphiql",
allow_queries_via_get: bool = False,
keep_alive: bool = False,
keep_alive_interval: float = 1,
subscription_protocols: List[str] = None,
connection_init_wait_timeout: float = 60,
context_getter: Callable = None,
root_value_getter: Callable = None
):
"""
Initialize ASGI GraphQL application.
Args:
schema: Strawberry GraphQL schema
graphql_ide: GraphQL IDE to serve
allow_queries_via_get: Allow GET requests for queries
keep_alive: Enable WebSocket keep-alive
keep_alive_interval: Keep-alive interval in seconds
subscription_protocols: Supported subscription protocols
connection_init_wait_timeout: WebSocket connection timeout
context_getter: Function to build request context
root_value_getter: Function to provide root value
"""
async def __call__(self, scope: dict, receive: Callable, send: Callable):
"""ASGI application callable."""Usage Example:
from strawberry.asgi import GraphQL
import uvicorn
# Create ASGI GraphQL app
app = GraphQL(
schema,
graphql_ide="graphiql",
allow_queries_via_get=True,
subscription_protocols=["graphql-transport-ws", "graphql-ws"]
)
# Custom context with ASGI
async def get_context(request):
return {
"user": await get_user_from_request(request),
"database": get_database_connection()
}
app_with_context = GraphQL(
schema,
context_getter=get_context
)
# Run with uvicorn
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)GraphQL view for AIOHTTP web applications.
class GraphQLView:
"""AIOHTTP view for GraphQL endpoints."""
def __init__(
self,
schema: Schema,
*,
graphql_ide: str = "graphiql",
allow_queries_via_get: bool = False,
context_getter: Callable = None,
root_value_getter: Callable = None
):
"""
Initialize AIOHTTP GraphQL view.
Args:
schema: Strawberry GraphQL schema
graphql_ide: GraphQL IDE to serve
allow_queries_via_get: Allow GET requests
context_getter: Function to build request context
root_value_getter: Function to provide root value
"""
async def __call__(self, request: web.Request) -> web.Response:
"""Handle AIOHTTP request."""Usage Example:
from aiohttp import web
from strawberry.aiohttp import GraphQLView
async def create_app():
# Custom context for AIOHTTP
async def get_context(request):
return {
"request": request,
"user": await get_user_from_session(request)
}
# Create GraphQL view
view = GraphQLView(
schema=schema,
context_getter=get_context
)
# Setup AIOHTTP app
app = web.Application()
app.router.add_route("*", "/graphql", view)
return app
# Run application
if __name__ == "__main__":
app = create_app()
web.run_app(app, host="localhost", port=8080)Integration with Django web framework through external package.
# Note: Requires strawberry-graphql-django package
from strawberry_django import auto
from strawberry_django.views import AsyncGraphQLView, GraphQLView
# Django model integration
@strawberry_django.type(models.User)
class User:
name: auto
email: auto
posts: List["Post"]
# Django views
class MyGraphQLView(GraphQLView):
schema = schema
graphql_ide = "graphiql"Usage Example:
# Django URLs
from django.urls import path
from strawberry.django.views import GraphQLView
urlpatterns = [
path("graphql/", GraphQLView.as_view(schema=schema)),
]
# Django settings integration
INSTALLED_APPS = [
# ... other apps
"strawberry.django",
]
# Custom Django context
class DjangoContext:
def __init__(self, request):
self.request = request
self.user = request.user if request.user.is_authenticated else None
def get_context(request):
return DjangoContext(request)
# Use with view
GraphQLView.as_view(
schema=schema,
context_getter=get_context
)GraphQL view for Flask web applications.
class GraphQLView:
"""Flask view for GraphQL endpoints."""
def __init__(
self,
schema: Schema,
*,
graphql_ide: str = "graphiql",
allow_queries_via_get: bool = False,
context_getter: Callable = None,
root_value_getter: Callable = None
):
"""
Initialize Flask GraphQL view.
Args:
schema: Strawberry GraphQL schema
graphql_ide: GraphQL IDE to serve
allow_queries_via_get: Allow GET requests
context_getter: Function to build request context
root_value_getter: Function to provide root value
"""
def __call__(self) -> Response:
"""Handle Flask request."""Usage Example:
from flask import Flask, g, request
from strawberry.flask import GraphQLView
app = Flask(__name__)
# Custom context for Flask
def get_context():
return {
"request": request,
"user": g.user if hasattr(g, "user") else None,
"db": get_database_connection()
}
# Create GraphQL view
view = GraphQLView(
schema=schema,
context_getter=get_context
)
# Add route
app.add_url_rule(
"/graphql",
view_func=view,
methods=["GET", "POST"]
)
# Middleware for user authentication
@app.before_request
def load_user():
token = request.headers.get("Authorization")
if token:
g.user = get_user_from_token(token)Integration with Starlette and Litestar ASGI frameworks.
# Litestar integration
class BaseContext:
"""Base context for Litestar integration."""
pass
HTTPContextType = TypeVar("HTTPContextType", bound=BaseContext)
WebSocketContextType = TypeVar("WebSocketContextType", bound=BaseContext)
def make_graphql_controller(
schema: Schema,
*,
path: str = "/graphql",
graphql_ide: str = "graphiql",
context_getter: Callable = None
) -> Type:
"""
Create Litestar controller for GraphQL.
Args:
schema: Strawberry GraphQL schema
path: GraphQL endpoint path
graphql_ide: GraphQL IDE to serve
context_getter: Function to build request context
Returns:
Litestar controller class
"""Usage Example:
from litestar import Litestar
from strawberry.litestar import make_graphql_controller
# Custom context
class MyContext:
def __init__(self, request, user=None):
self.request = request
self.user = user
def get_context(request) -> MyContext:
return MyContext(request, get_current_user(request))
# Create controller
GraphQLController = make_graphql_controller(
schema,
path="/graphql",
context_getter=get_context
)
# Create Litestar app
app = Litestar(
route_handlers=[GraphQLController],
debug=True
)Integration with Django Channels for WebSocket subscriptions.
class ChannelsConsumer:
"""Base Django Channels consumer."""
pass
class GraphQLHTTPConsumer(ChannelsConsumer):
"""HTTP consumer for GraphQL over Django Channels."""
def __init__(self, schema: Schema): ...
class GraphQLWSConsumer(ChannelsConsumer):
"""WebSocket consumer for GraphQL subscriptions."""
def __init__(self, schema: Schema): ...
class GraphQLProtocolTypeRouter:
"""Protocol type router for Django Channels."""
def __init__(
self,
schema: Schema,
*,
http_consumer: Type = GraphQLHTTPConsumer,
websocket_consumer: Type = GraphQLWSConsumer
): ...Usage Example:
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from strawberry.channels import GraphQLProtocolTypeRouter
# Django Channels routing
application = ProtocolTypeRouter({
"http": URLRouter([
# HTTP GraphQL
path("graphql/", GraphQLHTTPConsumer.as_asgi(schema=schema)),
]),
"websocket": AuthMiddlewareStack(
URLRouter([
# WebSocket subscriptions
path("graphql/", GraphQLWSConsumer.as_asgi(schema=schema)),
])
)
})
# Or use the protocol router helper
application = GraphQLProtocolTypeRouter(schema)GraphQL view for Sanic web framework.
class GraphQLView:
"""Sanic view for GraphQL endpoints."""
def __init__(
self,
schema: Schema,
*,
graphql_ide: str = "graphiql",
allow_queries_via_get: bool = False,
context_getter: Callable = None
): ...
async def __call__(self, request: SanicRequest) -> SanicResponse:
"""Handle Sanic request."""Usage Example:
from sanic import Sanic, response
from strawberry.sanic import GraphQLView
app = Sanic("GraphQL")
# Custom context
async def get_context(request):
return {
"request": request,
"user": await get_user_from_token(request.token)
}
# Create and add GraphQL view
view = GraphQLView(
schema=schema,
context_getter=get_context
)
app.add_route(view, "/graphql", methods=["GET", "POST"])GraphQL view for Quart async web framework.
class GraphQLView:
"""Quart view for GraphQL endpoints."""
def __init__(
self,
schema: Schema,
*,
graphql_ide: str = "graphiql",
allow_queries_via_get: bool = False,
context_getter: Callable = None
): ...
async def __call__(self) -> QuartResponse:
"""Handle Quart request."""Usage Example:
from quart import Quart, request
from strawberry.quart import GraphQLView
app = Quart(__name__)
async def get_context():
return {
"request": request,
"user": await get_current_user()
}
view = GraphQLView(
schema=schema,
context_getter=get_context
)
app.add_url_rule("/graphql", view_func=view, methods=["GET", "POST"])GraphQL view for AWS Chalice serverless framework.
class GraphQLView:
"""Chalice view for GraphQL endpoints."""
def __init__(
self,
schema: Schema,
*,
graphql_ide: str = None, # Usually disabled in serverless
context_getter: Callable = None
): ...
def __call__(self) -> ChaliceResponse:
"""Handle Chalice request."""Usage Example:
from chalice import Chalice
from strawberry.chalice import GraphQLView
app = Chalice(app_name="graphql-api")
def get_context():
return {
"current_request": app.current_request,
"user": get_user_from_jwt(app.current_request)
}
view = GraphQLView(
schema=schema,
context_getter=get_context
)
@app.route("/graphql", methods=["POST"])
def graphql():
return view()# Common context pattern across frameworks
class GraphQLContext:
def __init__(
self,
request,
user=None,
database=None,
cache=None
):
self.request = request
self.user = user
self.database = database
self.cache = cache
async def build_context(request):
# Extract user from authentication
user = None
auth_header = request.headers.get("Authorization")
if auth_header:
user = await authenticate_user(auth_header)
# Setup database connection
database = await get_database_connection()
# Setup cache
cache = get_cache_client()
return GraphQLContext(
request=request,
user=user,
database=database,
cache=cache
)from strawberry.extensions import MaskErrors
# Production error masking
production_schema = strawberry.Schema(
query=Query,
extensions=[
MaskErrors() # Hide internal errors in production
]
)
# Custom error formatting
class CustomErrorFormatter:
def format_error(self, error):
return {
"message": error.message,
"code": getattr(error.original_error, "code", "INTERNAL_ERROR"),
"path": error.path
}# Framework-specific CORS handling
# FastAPI
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://yourfrontend.com"],
allow_methods=["POST", "GET"],
allow_headers=["Content-Type", "Authorization"]
)
# Flask
from flask_cors import CORS
CORS(app, origins=["https://yourfrontend.com"])
# ASGI with middleware
from starlette.middleware.cors import CORSMiddleware
app = CORSMiddleware(
GraphQL(schema),
allow_origins=["https://yourfrontend.com"],
allow_methods=["POST", "GET"],
allow_headers=["Content-Type", "Authorization"]
)Install with Tessl CLI
npx tessl i tessl/pypi-strawberry-graphql