Skip to main content

HTTP-style WebSocket routing for Django Channels.

Project description

Django Channels Router (Backend, PyPI)

A lightweight Django + Channels router that lets your WebSocket consumers behave like HTTP endpoints.
Designed to pair seamlessly with @djanext/observable-socket.


Features

  • 🧭 Route names → handler methods (sayHelloon_say_hello)
  • ⚡ Both sync & async consumers
  • 🧩 Optional hydrate / dehydrate functions
  • 🔁 Built-in heartbeat support (PING/PONG)
  • 📦 Typed results and HTTP-style status codes

Requirements

  • Python ≥ 3.11
  • Django ≥ 4.2
  • Channels ≥ 4.0
  • Redis (or any supported channel layer)

Installation

pip install django-channels-router

In your project:

# routing.py
from django.urls import re_path
from django_channels_router import SocketRouterConsumer

websocket_urlpatterns = [
    re_path(r"ws/app/$", SocketRouterConsumer.as_asgi()),
]

Example Consumer

from django_channels_router import SocketRouterConsumer, StatusCodes

class AppSocket(SocketRouterConsumer):
    @SocketRouterConsumer.routes.setter
    def routes(self, _):
        self._routes = [
            {"route": "sayHello"},
            {"route": "getArticle",
             "hydrate": lambda headers, p: load_article(p["id"]),
             "dehydrate": lambda art: {"id": art.id, "title": art.title}
             },
        ]

    def on_say_hello(self, payload, headers):
        name = (payload or {}).get("name", "World")
        return {"status": StatusCodes.OK, "payload": f"Hello, {name}!"}

Async Example

from django_channels_router import AsyncSocketRouterConsumer

class AppSocketAsync(AsyncSocketRouterConsumer):
    @AsyncSocketRouterConsumer.routes.setter
    def routes(self, _):
        self._routes = [{"route": "sayHello"}]

    async def on_say_hello(self, payload, headers):
        return {"status": 200, "payload": {"msg": "Hello async!"}}

Serializing and Deserializing of messages

hydrate and dehydrate functions helps to focus only on logic part as these functions will handle deserializing and serializing automatically. To use them, first you need to implement the converters (loader, serializer, ...)

def load_article(headers, payload) -> Article | None:
    try:
        article_id = headers.get('id')
        if not article_id:
            return None
        return Article.objects.get(id=article_id) # assume id is of type string like uuid
    except Article.DoesNotExist:
        return None

def deserialize(headers, payload) -> Article | None:
    try:
        serializer = ArticleSerializer(data=payload)
        serializer.is_valid(raise_exception=True)
        return serializer.save()
    except serializers.ValidationError:
        return None

def serialize(article: Article) -> str:
    serializer = ArticleSerializer(article)
    return serializer.data

now these converters can be used as follows:

    class ArticleConsumer(SocketRouterConsumer):
        routes = [
            {route: get, hydrate: load_article, dehydrate: serialize},
            {route: create, hydrate: deserialize, dehydrate: serialize}
        ]
        
        def on_get(headers, payload):
            return {
                payload: payload, 
                # article gets fetched from DB in background using the `load_article` function
                # dehydrate will automatically serilize the article by running `serialize` function
                status: StatusCodes.OK if payload else StatusCodes.NOT_FOUND 
            }
            
        def on_create(headers, payload):
            if not payload: # deserialize function has returned None
                return {
                    payload: "Unable to create article",
                    status: StatusCodes.BAD_REQUEST
                }
                
            return {
                payload: payload,
                status: StatusCodes.CREATED
            }

Note:

hydrate function only applies if returned status code by user is 200 series. (199 < status code < 300)


Status Codes

Symbol Value Meaning
StatusCodes.OK 200 Success
StatusCodes.BAD_REQUEST 400 Malformed message
StatusCodes.NOT_FOUND 404 Unknown route
StatusCodes.INTERNAL_SERVER_ERROR 500 Handler failure

Good Practices

  • Always accept() connections in connect() / await accept().
  • Access result.get("payload") safely — avoid missing keys.
  • Use @classmethod route definitions if you plan to reuse the router base.
  • Keep payload JSON-serializable.

Frontend Client

Pair with @djanext/observable-socket
→ Handles auto-reconnect, multiple sockets, and sendAndWait() with Promises.


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_channels_router-1.0.3.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_channels_router-1.0.3-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file django_channels_router-1.0.3.tar.gz.

File metadata

  • Download URL: django_channels_router-1.0.3.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for django_channels_router-1.0.3.tar.gz
Algorithm Hash digest
SHA256 23d7b456260480c231ebb03993cb60f0a92a6a87ace5cf5f9903474584cdfa3f
MD5 718589c8f868f47c3c6a657b59f59a7a
BLAKE2b-256 274d43c69dff6f6fd2a3137b94f4a83f32a5cb79bced4f4ffe43c933f201836f

See more details on using hashes here.

File details

Details for the file django_channels_router-1.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for django_channels_router-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 25f1a4655c1ddbd265d08dbbefdd305f9113b7010a7c9c2a542c6c117159f358
MD5 987d97890f55b3603b7a82d42f7b2b7d
BLAKE2b-256 f682df0d9af3fa3196d467a22fc4b2f81d2765b33402c38e6e66aeb8ef30337c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page