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.
  • Simplified Middleware: Simple authentication wrappers for Django Sessions and Django Rest Framework (DRF) Tokens.
  • ASGI Native: Implements standard ProtocolTypeRouter and URLRouter for minimal overhead.
  • Subprotocol Auth: Supports secure token-based authentication via the Sec-WebSocket-Protocol header.
  • 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
        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
        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.

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:

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():
    broadcaster.broadcast("alerts_channel", 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

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

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

Built distribution (wheel)

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

Total release size: 38.3 kB

Release files / django_sockets-3.1.0b1.tar.gz

Download URL django_sockets-3.1.0b1.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
e6ce6b42cc3e60cbf475a635b61476f92ee6344e07cb25746e5f6a93468b5e4f
BLAKE2b-256 checksum
How to use checksums
208fdd1bdc078da9be56534b4bb68ff06e70c1c99aa9c3aef889bbbd66ec4b57
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.0b1-py3-none-any.whl

Download URL django_sockets-3.1.0b1-py3-none-any.whl
Size 20.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
27e5c9d4fea1d265f057012cfe33e208b0f6f30bd7ac61add5d89f3a5cc14c98
BLAKE2b-256 checksum
How to use checksums
dc85dee6fc0cf162b8f375422ca0f0dea400d784dfd9dbef4f6327900508d37f
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