Notifying clients about an event via DRF - django

I want to know if there really is a way of notifying clients about a certain event, VIA Djangorestframework. I know it can be achieved with websockets via channels, but I couldn't find any material that explains everything in a step by step process. If anyone can help me than thanks already.

After a long time, I find the solution.
Actually I am using django rest framework(DRF) and django channels. What I wanted to achieve was to send message to a particular user and not to broadcast it in a group, by the api request. That is of course, a call from asynchronous code.
You can achieve this by sending message to specific channels as mentioned in django channels official docs.
This is possible because whenever client joins the group, it is automatically assigned a channel that can uniquely identify that client. So what we need is that we save that channel into the database and whenever required, get it from database, as specified here. You can save the channel to the database like so
I hope this was helpful.

Related

Web API that itself sends data to client on availability

I am currently working with Django but I am stuck as I don't know if I am pursuing the right model given the nature of my application.
Problem Statement:
I have to make a REST API for a client such that whenever I get a trigger for a new entry/entries in my Database I have to send those to the client which is supposed to listen to a URL and has asked for data only once and now is open to receive data whenever available to him.
It is not sending a GET request now and then.
There will be different endpoints of the APIs. One is where I provide him all the new data available to me and in other where it asks for specific data (ex: '/myAPI/givemethis')
I can easily implement the second requirement as it is a simple request-response case.
I am not sure how to send him data that too on availability without him making a repeated request as client.
It appears a Publisher-Subscriber model is better suited for my use case but I don't know how to implement it on Django.
I bumped into several concepts like StreamingServices and MQTT but I am not sure what should be the right choice to go with.
Kindly provide some suggestions.

Django, Manage threads and websocket for a data visualisation website

I am a Django beginner and here is the project:
I am building a data visualization website. I am loading a continuous data stream and I want the client to be able to choose the data processing to apply (in python, IA treatments with TensorFlow for example). Once the treatments are chosen by the client, I want to be able to launch them in a thread and send the results to the client every X seconds in a WebSocket (and be able to process WebSocket messages coming from the client at the same time).
I have already done it with Flask but I don't succeed with Django.
I have followed many tutorials, in particular this one, which seems similar to what I want to do: https://www.neerajbyte.com/post/how-to-implement-websocket-in-django-using-channels-and-stream-websocket-data
The main issue is that I don't know how or even where to create my thread. I can't do it in an AsyncWebsocketConsumer class, because it doesn't allow me to launch a thread that is able to send a Websocket request (I need to launch an async function to be able to send a request and I can't launch an async function in a thread).
One solution proposed in the above tutorial to send data regularly is to create a management command. A solution that doesn't please me either because the function executed this way can't be chosen by the client in an AsyncWebsocketConsumer class.
So here I am, I'm really struggling to find the solution.
I have heard some things about Celery and Gunicorn from here and there. What do you think about these? And how can these solve my issue?
I am open to every piece of advice, every tutorial, every idea which could allow me to move forward in my project.

What role does Redis serve in Django Channels

Recently I've been using django channels makes its support websocket protocol, I use a microservice way, other components through connection django channels, but I have to write a Consumer class for each connection for receiving and handling, for example class Consumer(AsyncWebsocketConsumer):, which still use the redis, pointed out that this part is the official document as a channel layer storage, so it is as a message queue, the cache or other commonly used functions exist?
I write to find out if there is a Consumer for each connection, and whether I can think of it as acting as a message queue.
However, I have not found relevant materials to support my point of view.
Could you please tell me whether my understanding is correct or not? I sincerely hope that you can provide relevant materials for reference whether it is correct or not.
It depends on how you are using it. The primary purpose of redis in django-channel_layers is to store the necessary information required for different instances of consumers to communicate with one another.
For example, in the tutorial section of channels documentation, it is clear that Redis is used as a storage layer for channel names and group names. These are stored within Redis so that they can be accessed from any consumer instance. If for example, I create a group called 'users' and then add 3 different channel names to it, this information is stored in Redis. Now, whenever I want to send data to the channels in the group I can simply reference the group from my consumer and Django-channels will automatically retrieve the channel names stored under that group in Redis.
On the other hand, if you want to use consumers in a non-conventional way, that is, as background workers then Redis becomes a message queue. That's because when you send a message containing a task to be done by one of the background workers (a consumer that 'consumes' the tasks) those messages have to be stored somewhere so that the background workers can retrieve them as they finish up other tasks.

django-channels databinding on model.save()

I have a channels app that is using databinding. When changes are made with django admin they are being pushed to the web as expected. I have loop set up on a socket connection to do some long polling on a gpio unit and update the db, these changes are not being pushed to the web. Channels documentation says:
Signals are used to power outbound binding, so if you change the values of a model outside of Django (or use the .update() method on a QuerySet), the signals are not triggered and the change will not be sent out. You can trigger changes yourself, but you’ll need to source the events from the right place for your system.
How do I go about triggering these changes, as it happens with admin?
Thanks and please let me know if this is to vague.
The relevant low-level code is in lines 121-187 of channels/binding/base.py (at least in version 1.1.6). That's where the signals are received and processed. It involves a few different things, such as keeping track of which groups to send the messages to. So it's a little involved, but you can probably tease out how to do it, looking at that code.
The steps involved are basically:
Find the right groups for the client
Format your message in the same way that the databinding code would (see this section of the docs)
Send the message to all the relevant groups you found in step 1.
Alternatively, you might consider using a REST API such that the socket code submits a POST to the API (which would create a database record via the ORM in the normal way) rather than directly creating database records. Your signals will happen automatically in that case. djangorestframework (server-side) and requests (client-side, if you're using python for the long-polling code) are your friends if you want to go that way, for sure. If you're using another language for the long-polling client, there are many equivalent packages for REST API client work.
Good luck!

Use the same WebSocket to push messages to a client

I'm starting with WebSockets, I already built a chat web-application as an exercise and it went something like this:
Every user has an opened websocket connection at their arrival to the chat-room, and when new messages are available, they're simply pushed to each user. The different messages are then displayed using javaScript.
Now, I'm trying to push the exercise a bit further by creating a one-on-one chat. Basically, there will no longer be a unique chat-room but private chat conversations. A user should be able to talk to different people from the same page. (Something like Google chat or Facebook chat).
After thinking about ways to do so, I came down to two solutions:
Open multiple websocket connections. (if possible)
Use the same connection to handle all opened conversations. Basically, each message that is pushed to the client will carry a field saying to which conversation it belongs, a javaScript will then handle the display of each message under the right conversation.
To me, the second solution seems better than the first. So, my questions are:
1- Will this solution have any performance problems? (Lost messages...)
2- Is there any other-better way of doing this?
The way to go depends (IMHO) on what framework you are using to do this communication.
I (as you) would go for multiplexing (second option) where you use one connection to handle all communication.
I assume that your framework of choice supports publish/subscribe and multiplexing?
I can provide you with a simple example if you like.
Regards
Uffe, Team XSockets