Skip to main content

Django Sockets

PyPI version License: MIT

Simplified Django WebSocket integrations designed for speed, flexibility, and cloud-cache scaling (Valkey/Redis). Works seamlessly on single, distributed, or serverless cache setups.

  • ASGI Server Compatibility: Compatible with any standard ASGI server (such as Uvicorn, Daphne, or Hypercorn).
  • Multi-Framework: Can also be used in non-Django applications (Flask, FastAPI, or raw Python) for lightweight Pub/Sub messaging.

Key Features

  • Cache-Backed Pub/Sub: Async broadcasting using Redis or Valkey across standalone, sentinel, or cluster (RedisCluster) setups.
  • Async & Sync Handlers: Implement connect, receive, and disconnect hooks as either synchronous methods (def) or asynchronous coroutines (async def).
  • Multi-Channel Broadcasting: Broadcast to single channels or batches of channels with Redis pipelining.
  • Flexible Auth Middleware: Simple authentication wrappers for Django Sessions and DRF Tokens supporting query string (?token=...) and subprotocol (Sec-WebSocket-Protocol: Token.<token>) token passing.
  • ASGI Native: Implements standard ProtocolTypeRouter and URLRouter
  • Minimal Boilerplate: Define a class with connect, receive, and disconnect hooks and you're ready to go.

Installation & Setup

pip install django_sockets

Valkey/Redis Setup

To use broadcasting and pub/sub features, you need a Redis or Valkey cache server:

# Start a local Valkey cache via Docker
docker run -d -p 6379:6379 --name django_sockets_cache valkey/valkey:7

Quickstart (Django)

1. Define your Socket Server

Create a ws.py in your Django app:

from django.urls import path
from django_sockets.sockets import BaseSocketServer
from django_sockets.middleware import SessionAuthMiddleware
from django_sockets.utils import URLRouter


class MyCounterSocket(BaseSocketServer):
    def configure(self):
        # Configure cache hosts (optional, needed for pub/sub)
        self.hosts = [{"address": "redis://localhost:6379"}]

    def connect(self):
        # Scope-aware user extraction (supports sync 'def' or async 'async def')
        self.channel_id = f"user_{self.scope['user'].id}"
        self.subscribe(self.channel_id)

    def receive(self, data):
        # Broadcast incoming JSON to all subscribers of this channel
        # (Supports sync 'def receive' or async 'async def receive')
        self.broadcast(self.channel_id, data)


# Wrap with authentication middleware and URL routing
websocket_application = SessionAuthMiddleware(
    URLRouter(
        [
            path("ws/counter/", MyCounterSocket.as_asgi),
        ]
    )
)

2. Configure ASGI Entrypoint

In your Django asgi.py (ensure imports are ordered correctly to allow proper Django initialization):

import os
from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
django_asgi_app = get_asgi_application()

# Import django_sockets after Django initialization
from django_sockets.utils import ProtocolTypeRouter
from .ws import websocket_application

application = ProtocolTypeRouter(
    {
        "http": django_asgi_app,
        "websocket": websocket_application,
    }
)

Running the ASGI Server

You can run your Django ASGI application using any ASGI-compliant web server:

Uvicorn

pip install uvicorn
uvicorn myapp.asgi:application --reload

Daphne

pip install daphne
daphne -p 8000 myapp.asgi:application

Hypercorn

pip install hypercorn
hypercorn myapp.asgi:application --bind 127.0.0.1:8000

Guides & Examples

We provide detailed step-by-step tutorials and code samples:

  • Step-by-Step Django Tutorial (TUTORIAL.md): Build a fully-featured, user-scoped real-time counter using session or DRF token authentication from scratch.
  • Examples Directory:
    • examples/django/myapp: Full project showing standard Django Session authentication.
    • examples/django/myapp_drf: Full project showing DRF Token authentication.
    • examples/without_django: Standalone python pub/sub without Django dependencies.
  • Performance Benchmarks (benchmark.md): Detailed benchmark profiles covering pub/sub latency, burst throughput, payload scaling, fan-out scalability, and authentication middleware.

Non-Django Usage (Flask, FastAPI, Raw Python)

django_sockets can run without Django's registry:

1. Broadcaster (Sending from Flask/FastAPI)

Publish events from any HTTP route to WebSocket clients across single or multiple channels:

from flask import Flask, request
from django_sockets.broadcaster import Broadcaster

app = Flask(__name__)
broadcaster = Broadcaster(hosts=[{"address": "redis://localhost:6379"}])


@app.route("/alert", methods=["POST"])
def send_alert():
    # Broadcast to a single channel:
    broadcaster.broadcast("alerts_channel", request.json)

    # Or broadcast to multiple channels simultaneously with Redis pipelining:
    # broadcaster.broadcast(["alerts_channel", "audit_log"], request.json)
    # broadcaster.broadcast_many(["chan1", "chan2"], request.json)

    return {"status": "Alert sent"}

2. Running a Pure ASGI Server

Initialize BaseSocketServer manually in custom ASGI configurations or raw Python scripts:

import asyncio
from django_sockets.sockets import BaseSocketServer


async def my_send_handler(data):
    print("Sent:", data)


receive_queue = asyncio.Queue()
socket_server = BaseSocketServer(
    scope={},
    receive=receive_queue.get,
    send=my_send_handler,
    hosts=[{"address": "redis://localhost:6379"}],
)
socket_server.start_listeners()

Development & Testing

Run the full pytest suite:

uv run pytest

Run the performance benchmark suite:

uv run python utils/benchmark.py

For manual testing, manage the local Docker Valkey instance using:

uv run python utils/redis_start.py
# Run your manual scripts (e.g. uv run test/06_django_integration.py)
uv run python utils/redis_stop.py

Attributions

Some of the code in this repository is formed similarly to or inspired by channels_redis and django_channels. Many thanks to their authors for the original work and inspiration.

Metadata

Release files for django-sockets 3.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-sockets 3.1.0
File Size Uploaded
django_sockets-3.1.0.tar.gz 19.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-sockets 3.1.0
File Interpreter ABI Platform
django_sockets-3.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 42.4 kB

Release files / django_sockets-3.1.0.tar.gz

Download URL django_sockets-3.1.0.tar.gz
Size 19.8 kB
Tags Source
SHA-256 checksum
How to use checksums
81771057a481f208f260dd80c75fcb657deaaca309361f7a0508ae3f7b400ca0
BLAKE2b-256 checksum
How to use checksums
674d44e4f09a6786802fd8ad899df975e2c3f3a16ff6e9d81cafb522e2703a78
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / django_sockets-3.1.0-py3-none-any.whl

Download URL django_sockets-3.1.0-py3-none-any.whl
Size 22.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c1f2bb7bf298eb871942369db3931945236796fec80a9547a5f5c3b0e93e6565
BLAKE2b-256 checksum
How to use checksums
4b95e6c809038d0e4ffa3539108e63429b1e203b5a36e5a65c1227eb3ad7c225
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page