Skip to main content

Routing support for websockets.

Project description

websockets-routes

websockets does not do routing, and I don't like Sanic, so I rolled my own.

Routing backed by Routes.

Usage

Decorate your handlers by path, and serve the router.

import asyncio

import websockets
import websockets_routes

router = websockets_routes.Router()

@router.route("/thing/")
async def thing_list(ws, path):
    ...

start_server = websockets.serve(router.handle, ...)

loop = asyncio.get_event_loop()
loop.run_until_complete(start_server)
loop.run_forever()

By default, connections are closed immediately with 4040 if the URL does not match any of the registered routes.

Block connections during handshake

The router has its own serve() method that overrides the process_request() hook, making the server return an HTTP 404 during the handshake phase instead:

start_server = router.serve(...)

This way, a non-matching client never connects to the websocket handler at all.

The override is implemented via a custom WebSocket protocol, so you can subclass that if you need further customisation:

class MyProtocol(websockets_routes.Protocol):
    ...

start_server = websockets.serve(
    router,
    ...,
    create_protocol=MyProtocol,
    ...,
)

Access route parameters

The handler's second parameter is a RoutedPath instead of a plain str. This is a str subclass, so you can do anything you could as in websockets. There is one additional attribute, params, that allows you to access the matched route parameters.

@router.route("/thing/{id}")
async def thing_detail(ws, path):
    # Asumming this is accessed with "/thing/123".
    await ws.send(path)  # This sends a text frame "/thing/123".
    await ws.send(path.params["id"])  # Text frame "123".

Per-view handshake hooks

Decorate a class to provide per-view validation and additional processing:

import http

@router.route("/thing/{id}")
class ThingDetail:
    async def process_request(self, path, headers):
        thing_id = path.params["id"]
        thing = get_thing_or_none(thing_id)
        if thing is not None:
            # Pass additional context to handle().
            path.context["thing"] = thing
            return None
        message = f"thing {thing_id!r} not found\n"
        return (http.HTTPStatus.NOT_FOUND, [], message.encode("utf-8"))

    async def handle(self, ws, path):
        """Now this is only called if thing is found.
        """
        thing = path.context["thing"]  # Retrieve the context to use.

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

websockets-routes-0.2.tar.gz (4.3 kB view details)

Uploaded Source

Built Distribution

websockets_routes-0.2-py3-none-any.whl (4.0 kB view details)

Uploaded Python 3

File details

Details for the file websockets-routes-0.2.tar.gz.

File metadata

  • Download URL: websockets-routes-0.2.tar.gz
  • Upload date:
  • Size: 4.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.24.0

File hashes

Hashes for websockets-routes-0.2.tar.gz
Algorithm Hash digest
SHA256 20b6cb3f5ef29c6f6ae812e78b1550c2e99de2db64fe1b6a67d3204601f11f5f
MD5 cfa57d412d6107173e9f132e39bab35c
BLAKE2b-256 8d24e27a88c490fb00dfd0a428c99931fb7478fec07fbf70a60e8cf29795b214

See more details on using hashes here.

File details

Details for the file websockets_routes-0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for websockets_routes-0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 883fa232a4e2fc9178dcc41de0ddefb03350f8c33c54e799cee07de5c5cffe4d
MD5 b7f7aebfc5b6aa39d65ec14830085259
BLAKE2b-256 6db244ee377156bf25a4cb017b449aba9946ececf01099129cfbb8ff2cf13d97

See more details on using hashes here.

Supported by

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