Django Channels

Strawberry provides an integration with django-channels to enable subscriptions and WebSocket support with Django.

Overview

Django doesn’t support WebSockets out of the box. Django Channels extends Django to handle WebSockets and other asynchronous protocols. Strawberry’s Channels integration allows you to:

Installation

Install the required packages:

Terminal window
pip install channels daphne

For production deployments, you may also need a channel layer backend:

Terminal window
pip install channels-redis # For Redis-backed channel layers

Configuration

1. Update INSTALLED_APPS

Add daphne and channels to your INSTALLED_APPS in settings.py :

settings.py
INSTALLED_APPS = [
'daphne', # Must be before staticfiles for runserver override
'django.contrib.staticfiles',
# ... other apps
'channels',
'strawberry_django',
]

2. Configure ASGI Application

Set the ASGI application path:

settings.py
ASGI_APPLICATION = 'myproject.asgi.application'

3. Set Up ASGI Routing

Create or update your asgi.py file:

myproject/asgi.py
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
# Initialize Django ASGI application early to ensure AppRegistry is populated
# before importing any models
django_asgi_app = get_asgi_application()
# Import schema AFTER django setup
from myproject.schema import schema
from strawberry_django.routers import AuthGraphQLProtocolTypeRouter
application = AuthGraphQLProtocolTypeRouter(
schema,
django_application=django_asgi_app,
)

AuthGraphQLProtocolTypeRouter

strawberry_django provides AuthGraphQLProtocolTypeRouter , a convenience class that sets up GraphQL on both HTTP and WebSocket with authentication support.

from strawberry_django.routers import AuthGraphQLProtocolTypeRouter
application = AuthGraphQLProtocolTypeRouter(
schema, # Your Strawberry schema
django_application=django_asgi, # Optional: Django ASGI app for non-GraphQL routes
url_pattern="^graphql", # Optional: URL pattern (default: "^graphql")
)

What it provides

Custom URL Pattern

# Route GraphQL to /api/graphql instead of /graphql
application = AuthGraphQLProtocolTypeRouter(
schema,
django_application=django_asgi_app,
url_pattern="^api/graphql",
)

Difference from Strawberry’s GraphQLProtocolTypeRouter

Strawberry core provides GraphQLProtocolTypeRouter , but strawberry_django provides AuthGraphQLProtocolTypeRouter with these enhancements:

FeatureGraphQLProtocolTypeRouterAuthGraphQLProtocolTypeRouter
Auth middlewareNoYes (AuthMiddlewareStack)
Host validationNoYes (AllowedHostsOriginValidator)
request.user availableNoYes

Use AuthGraphQLProtocolTypeRouter when you need:

Channel Layers

For subscriptions that need to broadcast to multiple clients (e.g., chat applications), configure a channel layer:

settings.py
# Development (in-memory, single-process only)
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}
# Production (Redis)
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("127.0.0.1", 6379)],
},
},
}

Accessing User in Resolvers

With AuthGraphQLProtocolTypeRouter , you can access the authenticated user:

import strawberry
from strawberry.types import Info
@strawberry.type
class Query:
@strawberry.field
def me(self, info: Info) -> str:
user = info.context.request.user
if user.is_authenticated:
return f"Hello, {user.username}!"
return "Hello, anonymous!"

Running the Server

Development

With Daphne installed and configured, runserver automatically uses ASGI:

Terminal window
python manage.py runserver

Production

Use an ASGI server like Daphne, Uvicorn, or Hypercorn:

Terminal window
# Daphne
daphne myproject.asgi:application
# Uvicorn
uvicorn myproject.asgi:application --host 0.0.0.0 --port 8000
# Hypercorn
hypercorn myproject.asgi:application --bind 0.0.0.0:8000

Advanced: Custom Routing

For more complex setups, you can create custom routing:

myproject/asgi.py
import os
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from django.core.asgi import get_asgi_application
from django.urls import re_path
from strawberry.channels.handlers.http_handler import GraphQLHTTPConsumer
from strawberry.channels.handlers.ws_handler import GraphQLWSConsumer
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django_asgi_app = get_asgi_application()
from myproject.schema import schema
application = ProtocolTypeRouter({
"http": AuthMiddlewareStack(
URLRouter([
re_path(r"^graphql$", GraphQLHTTPConsumer.as_asgi(schema=schema)),
re_path(r"^", django_asgi_app),
])
),
"websocket": AllowedHostsOriginValidator(
AuthMiddlewareStack(
URLRouter([
re_path(r"^graphql$", GraphQLWSConsumer.as_asgi(schema=schema)),
])
)
),
})

Troubleshooting

Subscriptions not working

  1. Check ASGI_APPLICATION is correctly set in settings
  2. Ensure schema is imported after get_asgi_application() to avoid AppRegistryNotReady errors
  3. Use an ASGI server - standard runserver without Daphne uses WSGI

User is AnonymousUser

  1. Ensure you’re using AuthGraphQLProtocolTypeRouter (not GraphQLProtocolTypeRouter )
  2. Check that AuthMiddlewareStack is in your routing
  3. Verify session cookies are being sent with WebSocket requests

WebSocket connection refused

  1. Check ALLOWED_HOSTS in settings includes your hostname
  2. Ensure the URL pattern matches your client’s WebSocket URL
  3. Check browser console for CORS or security errors

See Also