Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/uranusjr/websockets-routes
Routing support for websockets
https://github.com/uranusjr/websockets-routes
Last synced: 2 months ago
JSON representation
Routing support for websockets
- Host: GitHub
- URL: https://github.com/uranusjr/websockets-routes
- Owner: uranusjr
- Created: 2020-08-11T11:14:22.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2020-10-28T10:10:32.000Z (about 4 years ago)
- Last Synced: 2024-10-31T05:51:38.802Z (3 months ago)
- Language: Python
- Size: 8.79 KB
- Stars: 9
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# `websockets-routes`
`websockets` [does not do routing](https://github.com/aaugustin/websockets/issues/311), and I don't like Sanic, so I rolled my own.
Routing backed by [`Routes`](https://routes.readthedocs.io/en/latest/).
## Usage
Decorate your handlers by path, and serve the router.
```python
import asyncioimport websockets
import websockets_routesrouter = 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:```python
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:```python
class MyProtocol(websockets_routes.Protocol):
...start_server = websockets.serve(
router,
...,
create_protocol=MyProtocol,
...,
)
```[WebSocket protocol]: https://websockets.readthedocs.io/en/stable/cheatsheet.html?highlight=protocol#server
### 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.
```python
@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:
```python
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.
```