Django-channels-jsonrpc
The Django-channels-jsonrpc is aimed to enable JSON-RPC functionnality on top of the excellent django channels project and especially their Websockets functionality. It is aimed to be:
- Fully integrated with Channels
- Fully implement JSON-RPC 1 and 2 protocol
- Easy integration
Tech
The only Django-channels-jsonrpc dependency is the Django channels project
Installation
Download and extract the latest pre-built release.
Install the dependencies and devDependencies and start the server.
$ pip install django-channels-jsonrpc
Use
See complete exmaple here, and in particular consumer.py
It is intended to be used as a Websocket consumer. See documentation except... simplier...
Start importing the JsonRpcWebsocketConsumer class
from channels_jsonrpc import JsonRpcWebsocketConsumer
And create the consumer
class MyJsonRpcWebsocketConsumer(JsonRpcWebsocketConsumer):
# Set to True if you want them, else leave out
strict_ordering = False
slight_ordering = False
def connection_groups(self, **kwargs):
"""
Called to return the list of groups to automatically add/remove
this connection to/from.
"""
return ["test"]
def connect(self, message, **kwargs):
"""
Perform things on connection start
"""
self.message.reply_channel.send({"accept": True})
print("connect")
# Do stuff if needed
def disconnect(self, message, **kwargs):
"""
Perform things on connection close
"""
print("disconnect")
# Do stuff if needed
Then the last step is to create the RPC methos hooks. IT is done with the decorator:
@MyJsonRpcWebsocketConsumer.rpc_method()
Like this:
@MyJsonRpcWebsocketConsumer.rpc_method()
def ping():
return "pong"
MyJsonRpcWebsocketConsumer.rpc_method() accept a string as a parameter to 'rename' the function
@MyJsonRpcWebsocketConsumer.rpc_method("mymodule.rpc.ping")
def ping():
return "pong"
Will now be callable with "method":"mymodule.rpc.ping" in the rpc call:
{"id":1, "jsonrpc":"2.0","method":"mymodule.rpc.ping","params":{}}
RPC methods can obviously accept parameters. They also return "results" or "errors":
@MyJsonRpcWebsocketConsumer.rpc_method("mymodule.rpc.ping")
def ping(fake_an_error):
if fake_an_error:
# Will return an error to the client
# --> {"id":1, "jsonrpc":"2.0","method":"mymodule.rpc.ping","params":{}}
# <-- {"id": 1, "jsonrpc": "2.0", "error": {"message": "fake_error", "code": -32000, "data": ["fake_error"]}}
raise Exception("fake_error")
else:
# Will return a result to the client
# --> {"id":1, "jsonrpc":"2.0","method":"mymodule.rpc.ping","params":{}}
# <-- {"id": 1, "jsonrpc": "2.0", "result": "pong"}
return "pong"
Testing
The JsonRpcWebsocketConsumer class can be tested the same way Channels Consumers are tested. See here
License
MIT
Have fun with Websockets!
Free Software, Hell Yeah!