Package: channels-binding
Channels Binding APIChannels Binding exposes an JSON API streaming system overchannels,
It’s designed to work as a full featured RestAPI via websocket, http, or both protocols combined.
in very few code lines, with a very simple and verboseless exchange structure,
where each django Models would be easily binded and come with native basics operations like ‘retrieve’, ‘search’, ‘update’, ‘create’, ‘delete’ and subscription.
We could made the comparaison with django restframework with the REST system.
It also provides react packages with ready-to-use pre configured tools and components to make easy Applications UIs.Channels-binding is a compilation of somes packages :https://pypi.org/project/channels-binding/for python/djangohttps://www.npmjs.com/package/@channels-binding/corefor node/reacthttps://www.npmjs.com/package/@channels-binding/muifor material-ui integrationSummaryDemo (soon)CapabilitiesExchanges Structure OverviewsGettings StartedCustom Events BindingCapabilitiesSupport of ‘retrieve’, ‘form’, ‘search’, ‘list’’update’, ‘create’, ‘save’, ‘delete’, ‘subscribe’ eventsSupport of django signals to refresh any connected instance with React toolsSupport of native django Queryset into React (Material-UI Tables available)Support of native django Form into React (Material-UI Fields available)Support of Hashed events for targeted subscribers (example: 2 lists on the same stream/event/model but with different filtering)Auto channels subscribing groups of interest ‘retrieve’, ‘list’, ‘delete’Custom bindings events through decoratorsCompatible with Django restframework serializers (soon ready)Both Async or Sync Consumers (not yet)Both HTTP Rest or WS API  (not yet)Exchanges Structure OverviewsSELFSEND=>{event:"auth.User.search",data:{page:2}}SELFRECEIVE=>{event:"auth.User.search",data:{page:2,limit:25,count:102,rows:[{id:5763,username:"Admin",email:"admin@admin.com"},...]}}SELFSEND=>{event:"auth.User.retrieve",data:{id:5763}}SELFRECEIVE=>{event:"auth.User.retrieve",data:{id:5763,username:"Admin",email:"admin@admin.com",...andMoreDetails}}SELFSEND=>{event:"auth.User.update",data:{id:5763,username:"Changed Username"}}SELFRECEIVE=>{event:"auth.User.update",data:{success:true}}GROUPRECEIVE=>{event:"auth.User.retrieve",data:{id:5763,username:"Changed Username",email:"admin@admin.com",...andMoreDetails}}Getting StartedAssume that you have already django>=1.8 and channels>=2.0.0 installedAddchannels-bindingto requirements.txtpipinstallchannels-bindingAddchannels_bindingtoINSTALLED_APPSINSTALLED_APPS=('channels','channels_binding',)Configure some optionnalsSETTINGSCHANNEL_LAYERS={'default':{# ...someChannelsConfig},}CHANNELS_BINDING={"AUTHENTIFICATION_CLASSES":('authentification.AuthenticationStrategyClass',),"DEFAULT_PAGE_SIZE":25,"ANONYMOUS_CONNECTION_ALLOWED":False,# Reject connection of non connected users}Add a new AsyncConsumer in your asgi application routing (Read the channels docs)# asgi.pyfromdjango.urlsimportpathfromchannels.sessionsimportSessionMiddlewareStackfromchannels.routingimportProtocolTypeRouter,URLRouterfromchannels_binding.consumersimportAsyncConsumerapplication=ProtocolTypeRouter({'websocket':SessionMiddlewareStack(URLRouter([path('',AsyncConsumer,name="root"),]))})Add bindinds inside an app or root bindigns folder# apps/your_app/bindings.pyfromchannels_binding.consumersimportAsyncBindingfrom.modelsimportYourModel'''
    All bindings in apps/*/bindings.py or app/bindings/*.py are auto discovered, like models.py
'''classYourModelBinding(AsyncBinding):model=YourModel# stream = by default '{app_name.model_name}' if model is set# permission_class = by default None (may change in future)# serializer_class = by default None (soon compatible with restframwork serializer)# queryset = by default YourModel.objects.all()# page_size = by default 25 rows for the 'search' and 'list' events# post_save_retrieve = by default True, if is True, an instance post_save send the 'retrieve' event to all the stream subscribersLet’s start to communicate with a simple retrieve action on a frontal javascript thirdparty// Soon React example...varws=newWebSocket("ws://"+window.location.host+"/")ws.onmessage=function(e){console.log(e.data)/*
       Receive:
       {
            event: "your_app.YourModel.retrieve",
            data: {
                id: 5763,
                ...someData
            }
       }
    */}ws.send(JSON.stringify({event:"your_app.YourModel.retrieve",data:{id:5763}}))React front integrationAssume that you have already react installednpm install @channels-binding/coreFor an integration with material-uinpm install @channels-binding/muiCustom Events BindingAdd a full custom binding with# apps/your_app/bindings.pyfromchannels_binding.consumersimportAsyncBinding,bindclassYourCustomBinding(AsyncBinding):stream='custom_stream'@bind('custom_event')asyncdefhandle_custom_event(self,data):sender=data['sender']# Direct reflect the reponse to the current socket pipeawaitself.reflect('custom_event',{'msg':f'This a reflected response for{sender}'})# Send an event to this stream subscribersawaitself.dispatch('custom_group_event',{'msg':f'This a dispatched response to the custom_stream subscriber from{sender}'})# Send an event to this stream subscribersawaitself.broadcast('custom_all_event',{'msg':f'This a dispatched response to the all layers from{sender}'})Let’s try this on a frontal javascript thirdpartyvarws=newWebSocket("ws://"+window.location.host+"/")ws.onmessage=function(e){console.log(e.data)/*
       Receive (reflected):
       {
            event: "custom_stream.custom_event",
            data: {
                msg: 'This a reflected response for me!!!'
            }
       }
       Receive (from group to all "custom_stream" subscribers):
       {
            event: "custom_stream.custom_group_event",
            data: {
                msg: 'This a dispatched response to the custom_stream subscriber from me!!!'
            }
       }
       Receive (broadcasted to all):
       {
            event: "custom_stream.custom_all_event",
            data: {
                msg: 'This a dispatched response to the all layers from me!!!'
            }
       }
    */}ws.send(JSON.stringify({event:"custom_stream.custom_event",data:{sender:'me!!!'}}))