All Projects → linuxlewis → Channels Api

linuxlewis / Channels Api

Licence: mit
RESTful Websocket APIs with Django Rest Framework and Channels

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Channels Api

Fosswebsite
A club management system that handles student details, progress, events, achievements, attendance, status updates, teams and workshop registrations. This is the official [email protected] website
Stars: ✭ 242 (-31.44%)
Mutual labels:  django, django-rest-framework
Django Hashid Field
Django Model Field that uses Hashids to obscure the value
Stars: ✭ 256 (-27.48%)
Mutual labels:  django, django-rest-framework
Django Rest Registration
User-related REST API based on the awesome Django REST Framework
Stars: ✭ 240 (-32.01%)
Mutual labels:  django, django-rest-framework
Django Rest Passwordreset
An extension of django rest framework, providing a configurable password reset strategy
Stars: ✭ 238 (-32.58%)
Mutual labels:  django, django-rest-framework
Openciviwiki
Building a Better Democracy for the Internet Age
Stars: ✭ 275 (-22.1%)
Mutual labels:  django, django-rest-framework
Tacticalrmm
A remote monitoring & management tool, built with Django, Vue and Go.
Stars: ✭ 231 (-34.56%)
Mutual labels:  django, django-rest-framework
Django Practice Book
《Django企业开发实战》已出版
Stars: ✭ 251 (-28.9%)
Mutual labels:  django, django-rest-framework
Ownphotos
Self hosted alternative to Google Photos
Stars: ✭ 2,587 (+632.86%)
Mutual labels:  django, django-rest-framework
Presentations
Collection of presentations for advanced Python topics
Stars: ✭ 264 (-25.21%)
Mutual labels:  django, django-rest-framework
Django Url Filter
Django URL Filter provides a safe way to filter data via human-friendly URLs.
Stars: ✭ 259 (-26.63%)
Mutual labels:  django, django-rest-framework
Docker Django Nginx Uwsgi Postgres Tutorial
Docker + Django + Nginx + uWSGI + Postgres 基本教學 - 從無到有 ( Docker + Django + Nginx + uWSGI + Postgres Tutorial )
Stars: ✭ 334 (-5.38%)
Mutual labels:  django, django-rest-framework
Drf Flex Fields
Dynamically set fields and expand nested resources in Django REST Framework serializers.
Stars: ✭ 350 (-0.85%)
Mutual labels:  django, django-rest-framework
Rest Api
Learn how to build your own REST API with Python, Django, and the Django Rest Framework.
Stars: ✭ 232 (-34.28%)
Mutual labels:  django, django-rest-framework
Django Rest Framework Datatables
Seamless integration between Django REST framework and Datatables.
Stars: ✭ 241 (-31.73%)
Mutual labels:  django, django-rest-framework
Djangochannelsrestframework
A Rest-framework for websockets using Django channels-v3
Stars: ✭ 224 (-36.54%)
Mutual labels:  django, django-rest-framework
Tweetme 2
Build a twitter-like app in Django, Bootstrap, Javascript, & React.js. Step-by-Step.
Stars: ✭ 247 (-30.03%)
Mutual labels:  django, django-rest-framework
Blogbackendproject
Backend code for my blogs, develop with Django Rest framework.
Stars: ✭ 204 (-42.21%)
Mutual labels:  django, django-rest-framework
Treeherder
A system for managing CI data for Mozilla projects
Stars: ✭ 212 (-39.94%)
Mutual labels:  django, django-rest-framework
Django Elasticsearch Dsl Drf
Integrate Elasticsearch DSL with Django REST framework.
Stars: ✭ 258 (-26.91%)
Mutual labels:  django, django-rest-framework
Django Rest Framework Jwt
JSON Web Token Authentication support for Django REST Framework
Stars: ✭ 3,105 (+779.6%)
Mutual labels:  django, django-rest-framework

Channels API

.. image:: https://travis-ci.org/linuxlewis/channels-api.svg?branch=master :target: https://travis-ci.org/linuxlewis/channels-api

Channels API exposes a RESTful Streaming API over WebSockets using channels. It provides a ResourceBinding which is comparable to Django Rest Framework's ModelViewSet. It is based on DRF serializer classes.

It requires Python 2.7 or 3.x, Channels <=1.1.8.1, Django <=1.11, and Django Rest Framework 3.x

You can learn more about channels-api from my talk at the SF Django Meetup <https://vimeo.com/194110172#t=3033>__ or PyBay 2016 <https://www.youtube.com/watch?v=HzC_pUhoW0I>__

Table of Contents

  • Getting Started <#getting-started>__
  • ResourceBinding <#resourcebinding>__
  • Subscriptions <#subscriptions>__
  • Custom Actions <#custom-actions>__
  • Permissions <#permissions>__

How does it work?

The API builds on top of channels' WebsocketBinding class. It works by having the client send a stream and payload parameters. This allows us to route messages to different streams (or resources) for a particular action. So POST /user would have a message that looks like the following

.. code:: javascript

var msg = {
  stream: "users",
  payload: {
    action: "create",
    data: {
      email: "[email protected]",
      password: "password"
    }
  }
}

ws.send(JSON.stringify(msg))

Why?

You're already using Django Rest Framework and want to expose similar logic over WebSockets.

WebSockets can publish updates to clients without a request. This is helpful when a resource can be edited by multiple users across many platforms.

Getting Started

This tutorial assumes you're familiar with channels and have completed the Getting Started <https://channels.readthedocs.io/en/latest/getting-started.html>__

  • Add channels_api to requirements.txt

.. code:: bash

pip install channels_api

  • Add channels_api to INSTALLED_APPS

.. code:: python

INSTALLED_APPS = (
    'rest_framework',
    'channels',
    'channels_api'
)
  • Add your first resource binding

.. code:: python

# polls/bindings.py

from channels_api.bindings import ResourceBinding

from .models import Question
from .serializers import QuestionSerializer

class QuestionBinding(ResourceBinding):

    model = Question
    stream = "questions"
    serializer_class = QuestionSerializer
    queryset = Question.objects.all()
  • Add a WebsocketDemultiplexer to your channel_routing

.. code:: python

# proj/routing.py


from channels.generic.websockets import WebsocketDemultiplexer
from channels.routing import route_class

from polls.bindings import QuestionBinding

class APIDemultiplexer(WebsocketDemultiplexer):

    consumers = {
      'questions': QuestionBinding.consumer
    }

channel_routing = [
    route_class(APIDemultiplexer)
]

That's it. You can now make REST WebSocket requests to the server.

.. code:: javascript

var ws = new WebSocket("ws://" + window.location.host + "/")

ws.onmessage = function(e){
    console.log(e.data)
}

var msg = {
  stream: "questions",
  payload: {
    action: "create",
    data: {
      question_text: "What is your favorite python package?"
    },
    request_id: "some-guid"
  }
}
ws.send(JSON.stringify(msg))
// response
{
  stream: "questions",
  payload: {
    action: "create",
    data: {
      id: "1",
      question_text: "What is your favorite python package"
    }
    errors: [],
    response_status: 200
    request_id: "some-guid"
  }
}
  • 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.

.. code:: python

# proj/urls.py

from django.conf.urls import url, include

    urlpatterns = [
        url(r'^channels-api/', include('channels_api.urls'))
    ]

ResourceBinding

By default the ResourceBinding implements the following REST methods:

  • create
  • retrieve
  • update
  • list
  • delete
  • subscribe

See the test suite for usage examples for each method.

List Pagination

Pagination is handled by django.core.paginator.Paginator

You can configure the DEFAULT_PAGE_SIZE by overriding the settings.

.. code:: python

settings.py

CHANNELS_API = { 'DEFAULT_PAGE_SIZE': 25 }

Subscriptions

Subscriptions are a way to programmatically receive updates from the server whenever a resource is created, updated, or deleted

By default channels-api has implemented the following subscriptions

  • create a Resource
  • update any Resource
  • update this Resource
  • delete any Resource
  • delete this Resource

To subscribe to a particular event just use the subscribe action with the parameters to filter

.. code:: javascript

// get an event when any question is updated

var msg = { stream: "questions", payload: { action: "subscribe", data: { action: "update" } } }

// get an event when question(1) is updated var msg = { stream: "questions", payload: { action: "subscribe", pk: "1", data: { action: "update" } } }

Custom Actions

To add your own custom actions, use the detail_action or list_action decorators.

.. code:: python

from channels_api.bindings import ResourceBinding
from channels_api.decorators import detail_action, list_action

from .models import Question
from .serializers import QuestionSerializer

class QuestionBinding(ResourceBinding):

    model = Question
    stream = "questions"
    serializer_class = QuestionSerializer
    queryset = Question.objects.all()

    @detail_action()
    def publish(self, pk, data=None, **kwargs):
        instance = self.get_object(pk)
        result = instance.publish()
        return result, 200

    @list_action()
    def report(self, data=None, **kwargs):
        report = self.get_queryset().build_report()
        return report, 200

Then pass the method name as "action" in your message

.. code:: javascript

// run the publish() custom action on Question 1 var msg = { stream: "questions", payload: { action: "publish", data: { pk: "1" } } }

// run the report() custom action on all Questions var msg = { stream: "questions", payload: { action: "report" } }

Permissions

Channels API offers a simple permission class system inspired by rest_framework. There are two provided permission classes: AllowAny and IsAuthenticated.

To configure permissions globally use the setting DEFAULT_PERMISSION_CLASSES like so

.. code:: python

# settings.py

CHANNELS_API = {
    'DEFAULT_PERMISSION_CLASSES': ('channels_api.permissions.AllowAny',)

}

You can also configure the permission classes on a ResourceBinding itself like so

.. code:: python

from channels_api.permissions import IsAuthenticated

class MyBinding(ResourceBinding):
    permission_classes = (IsAuthenticated,)

Lastly, to implement your own permission class, override the has_permission of BasePermission.

.. code:: python

from channels_api.permissions import BasePermission

class MyPermission(BasePermission):

    def has_permission(self, user, action, pk):

        if action == "CREATE":
            return True
        return False
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].