Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

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.0b3

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.0b3
File Size Uploaded
django_sockets-3.1.0b3.tar.gz 19.9 kB Details

Built distribution (wheel)

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

Total release size: 42.2 kB

Release files / django_sockets-3.1.0b3.tar.gz

Download URL django_sockets-3.1.0b3.tar.gz
Size 19.9 kB
Tags Source
SHA-256 checksum
How to use checksums
5781d2dcedf6dd2ab4113f6f3764dc65b7f6e0510b3a0c95f2ef9207c4c990fa
BLAKE2b-256 checksum
How to use checksums
149c6c43c46d83799ffa82dc0370346bf411eff613f124030f8a269253f66387
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.0b3-py3-none-any.whl

Download URL django_sockets-3.1.0b3-py3-none-any.whl
Size 22.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4d87e68253d03c740bd500d310cf339a550144d33f3fd3118d8c383177da97db
BLAKE2b-256 checksum
How to use checksums
6df9f934494c5003ccca799938eca97c3039d25eac82be8099a76150552f4e18
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