daphne

The ASGI HTTP, HTTP/2, and WebSocket server that powers Django Channels.

Tool
PyPI
v4.2.3
2,679stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
67/100Good
Development Activity68
Maintenance24
Community76
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
58/100Fair
Architecture72
Code Quality68
Innovation55
Learning Curve35

Daphne is a protocol server built for the ASGI (Asynchronous Server Gateway Interface) and ASGI-HTTP specifications, originally developed to run Django Channels applications. It terminates HTTP/1.1, HTTP/2, and WebSocket connections in a single process and hands each request off to an ASGI application callable, automatically negotiating which protocol a given connection is using so a project doesn’t need separate URL prefixes for WebSocket versus HTTP endpoints.

Under the hood it’s a thin, purpose-built layer on top of Twisted: an asyncio event loop is installed as Twisted’s reactor at import time, so Daphne bridges Twisted’s mature networking stack (endpoint strings, TLS, HTTP/2 support) with asyncio-native ASGI applications like Django’s own async views and Channels consumers. It ships as both a library (daphne.server.Server) and a CLI (daphne), and it’s the reference server most Django Channels tutorials assume you’re running in production.

What You Get

  • A production-capable ASGI server for HTTP/1.1, HTTP/2, and WebSocket traffic in one process, with automatic protocol negotiation per connection
  • A daphne CLI that binds to TCP host/port, a UNIX socket, or an inherited file descriptor, with Twisted endpoint-description-string support for advanced binding (including TLS)
  • Native HTTP/2 termination when Twisted’s http2 and tls extras are installed, requiring no separate reverse proxy for HTTP/2 support
  • Root-path (SCRIPT_NAME) support via either a Daphne-Root-Path header or a --root-path flag, for mounting an ASGI app under a URL prefix behind a proxy
  • A daphne.testing module exposing DaphneTestingInstance and TestApplication for spinning up a real Daphne process in tests and asserting on what it received

Common Use Cases

  • Serving a Django Channels project’s ASGI app (HTTP views plus WebSocket consumers) in production, invoked directly as daphne myproject.asgi:application
  • Terminating TLS and HTTP/2 for an ASGI app without a separate proxy, using Twisted’s ssl: endpoint syntax and PEM key/cert files
  • Running behind a reverse proxy over a UNIX socket for lower overhead and simpler process isolation than a TCP loopback connection
  • Embedding daphne.server.Server directly inside another Python process (rather than shelling out to the CLI) when a tool needs programmatic control over startup and shutdown

Under The Hood

Architecture Daphne is organized as three cooperating layers: cli.py parses arguments and endpoint descriptions into Twisted endpoint strings; server.py owns the Server class, which installs an asyncio-backed Twisted reactor, builds an HTTPFactory and WebSocketFactory, binds each configured endpoint via serverFromString, and drives the Twisted reactor’s event loop; and http_protocol.py/ws_protocol.py implement the per-connection WebRequest/WebSocketProtocol classes that translate raw Twisted http.Request/Autobahn WebSocket callbacks into ASGI scope/receive/send calls against the application callable. Protocol negotiation for HTTP vs. WebSocket upgrade happens inside HTTPFactory, so a single listening port can serve both without separate URL prefixes. If the application object changes shape, the guarantee_single_callable compatibility shim in cli.py is the piece that absorbs old two-callable ASGI apps, keeping the rest of the pipeline single-callable.

Tech Stack The project is pure Python (99.8% of the codebase) built on Twisted (twisted[tls]>=22.4) for its networking/reactor and HTTP/2 support, Autobahn (autobahn>=22.4.2) for the WebSocket protocol implementation, and asgiref>=3.5.2,<4 for the ASGI compatibility layer shared with Django/Channels. Packaging is setuptools-based via pyproject.toml with a dynamic version read from daphne.__version__, and the package exposes a console-script entry point (daphne = daphne.cli:CommandLineInterface.entrypoint). There is no separate build step beyond wheel packaging — it ships as plain Python.

Code Quality Tests live under tests/ using Python’s unittest.TestCase (via pytest as the runner) plus hypothesis for property-based endpoint-string parsing tests, and cover the CLI argument/endpoint parsing, HTTP request/response handling, WebSocket handling, checks, and packaging metadata explicitly (test_cli.py, test_http_request.py, test_http_response.py, test_websocket.py, test_packaging.py). CI (.github/workflows/tests.yml) runs the suite across Python 3.10–3.14 on both Ubuntu and Windows via tox. Style is enforced with black, isort, and flake8 (with flake8-bugbear) through pre-commit, and mypy is listed as a test-extra dependency, though type coverage in the core modules themselves is thin — most functions rely on docstrings and defaults rather than annotations.

What Makes It Unique Daphne’s specific niche is being the server that bridges Twisted’s long-lived, battle-tested endpoint/TLS/HTTP-2 machinery with asyncio-native ASGI applications, rather than being built asyncio-first like Uvicorn or Hypercorn. That gives it access to Twisted’s endpoint-description-string mini-language (ssl:443:privateKey=...) and txacme-based automatic Let’s Encrypt certificates without extra glue, at the cost of installing its own asyncio event loop as the Twisted reactor on import — a deliberate, documented trade-off that the project warns about explicitly when another reactor is already installed.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search