Skip to main content

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


Download files

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

Source Distribution

channels_api-0.1.4.tar.gz (8.0 kB view hashes)

Uploaded Source

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