Helps build a REST-like API on top of WebSockets using channels.
Project description
Channels API
Channels API exposes a REST-like Streaming API over WebSockets using channels. It provides a ModelConsumer which is comparable to Django Rest Framework’s ModelViewSet. It is based on DRF serializer classes.
It requires Python 3, Django 1.8, and Django Rest Framework 3.0
Table of Contents
How does it work?
The API works by having the WebSocket client send a method parameter. This follows the format of resource.method. So POST /user would have a message payload that looks like the following:
{method: "user.create", email: "test@test.com", password: "1Password" }
Why?
You’re already using Django Rest Framework and want to expose the same logic over WebSockets. WebSockets has lower overhead and provides other functionality then HTTP.
Getting Started
This tutorial assumes you’re familiar with channels and have completed the Getting Started
Add channels_api to requirements.txt
Add channels_api to INSTALLED_APPS
INSTALLED_APPS = (
'rest_framework',
'channels',
'channels_api'
)
Add API consumer to route websockets to API channels
# proj/routing.py
from channels.routing import include
channel_routing = [
include('channels_api.routing.channel_routing'),
]
Add your first model consumer
# polls/consumers.py
from channels_api.generics import ModelConsumer
from .models import Question
from .serializers import QuestionSerializer
class QuestionConsumer(ModelConsumer):
model = Question
serializer_class = QuestionSerializer
queryset = Question.objects.all()
# proj/routing.py
from channels.routing import include, route_class
from polls.consumers import QuestionConsumer
channel_routing = [
include('channels_api.routing.channel_routing'),
route_class(QuestionConsumer, path='/')
]
That’s it. You can now make REST WebSocket requests to the server.
var ws = new WebSocket("ws://" + window.location.host + "/")
ws.onmessage = function(e){
console.log(e.data)
}
ws.send(JSON.stringify({method: "question.create", question_text: "What is your favorite python package?"}))
//'{"question_text":"What is your favorite python package?","id":1}'
Add the channels debugger page (Optional)
This page is helpful to debug API requests from the browser and see the response. It is only designed to be used when DEBUG=TRUE.
# proj/urls.py
from django.conf.urls import include
urlpatterns = [
url(r'^channels-api/', include('channels_api.urls'))
]
ModelConsumer
By default the ModelConsumer implements the following REST methods: create, retrieve, update, list, delete
They will be mapped to modelname.method respectively.
Custom Method
To add a custom method just define the method on the consumer class and add the method name to the variable available_methods
class UserConsumer(ModelConsumer):
model = User
serializer_class = UserSerializer
queryset = User.objects.all()
available_methods = ModelConsumer.available_methods + ('invite', )
def invite(self, message, **kwargs):
content = self.get_content()
# email.send(content["email"])
return content
This will be automatically mapped to the user.invite channel.
Parser Classes
Parser classes parse the params from the message content
By default channels_api removes the method key and passes all params forward.
You might want to implement a custom format, using a params key.
# proj/parsers.py
from channels_api import parsers
class CustomParser(formatters.BaseParser):
def parse(self):
return super().parse()['params']
Update the configuration
# proj/settings.py
CHANNELS_API = {
"DEFAULT_PARSER_CLASS": "proj.parsers.CustomParser"
}
Now to update the example from above
ws.send(JSON.stringify({method: "question.create", params: { question_text: "What is your favorite python package?"}}))
//'{"question_text":"What is your favorite python package?","id":1}'
Formatter Classes
Formatter classes format the output of the consumer response.
By default channels_api just returns the response directly from the serializer.
To add some additional formatting of the response (status codes, error codes, meta objects) just subclass formatters.BaseFormatter and update the configuration.
# proj/formatters.py
from channels_api import formatters
class CustomFormatter(formatters.BaseFormatter):
def format(self):
return {"data": self.data, "errors": self.error }
Then you just need to configure channels_api to use the formatter class
# proj/settings.py
CHANNELS_API = {
"DEFAULT_FORMATTER_CLASS": "proj.formatters.CustomFormatter"
}
The Output from the example above will now look like this .. code:: javascript
‘{“data”:{“question_text”:”What is your favorite python package?”,”id”:1}, “errors”: null}’
Roadmap
- 0.2
pagination for list
formatter classes for response formatting
- 0.3
permissions
testproject
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file channels_api-0.1.4.tar.gz
.
File metadata
- Download URL: channels_api-0.1.4.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 556c31771d99689b1a49d5162c1ef8657199a79e49ecfabc9f482f17d7d32ad8 |
|
MD5 | 4901f8b6f7d212a94c0e7fc90654f35a |
|
BLAKE2b-256 | 3ab6f804c9798db5820d49771af6f11d905ce198c92f9ea9c6dd73c5fa4d41ee |