Do I need to change my normal Django code when introducing Django Channels? - django

Hello I am a beginner in the python world, so I am still trying to understand the care when working with ASGI. I read some tutorials and documentation, as well as watched some videos on youtube. However, I was unsure on some points.
I have a small backend application using Django + Django Rest Framework.
My code is very trivial, composed of the most common concepts in the framework: views, serializers, models, urls, etc. In addition, I use a relational database.
My environment is this:
Python 3.8
Django 3
Django Rest Framework 3.11
Now, I need to add support for WebSockets and I did the basic configuration described in the Django Channels tutorial:
I installed Django Channels 2.4.0 (Daphene 2.5.0)
Added 'channels' to INSTALLED_APPS
I created a routing.py file with an empty ProtocolTypeRouter
I added ASGI_APPLICATION to my settings.py
I configured the asgi.py file to use channels
At the moment, I have not configured any channel layers
At the moment, I haven't created any WebSocket endpoint
After these configurations the runserver is using an ASGI development server and apparently my REST endpoints are all working.
Some questions:
Considering that all my code is synchronous, wouldn't it be necessary to make any adjustments to it?
This configuration above, already does all the magic necessary for my synchronous code to be executed safely in daphene considering that it is an ASGI server?
Can I serve normal HTTP and WebSockets requests using only ASGI in a reliable and stable manner? Or, is it recommended to serve HTTP traffic using WSGI and leave only WebSockets traffic to daphene?
Where exactly should care be taken regarding synchronous code?

These are my answers based on previous experiences with Django Channels 2 ...
1) Considering that all my code is synchronous, wouldn't it be necessary to make any adjustments to it?
You can safely keep your existing sync code: no adjustments are required; just make sure to call the “sync version” of django-channels API (i.e. SyncConsumer instead of AsyncConsumer).
On the other hand, Channel Layers uses a different approach, and provides only an async version.
When the call is issued from sync code, you need to use the async_to_sync wrapper; for example:
from asgiref.sync import async_to_sync
async_to_sync(channel_layer.group_send)(
group, {
"type": 'data_received',
"content": data,
})
2) This configuration above, already does all the magic necessary for my synchronous code to be executed safely in daphene considering that it is an ASGI server?
The single missing details is (in settings file):
ROOT_URLCONF = 'project.urls'
3) Can I serve normal HTTP and WebSockets requests using only ASGI in a reliable and stable manner? Or, is it recommended to serve HTTP traffic using WSGI and leave only WebSockets traffic to daphene?
With Channels 2, you can safely choose to use Daphne for both HTTP and WebSockets requests, since Daphne will auto-negotiates between HTTP and WebSocket; this is what I usually do in my projects.
Splitting HTTP and WebSocket traffic, thus:
running standard HTTP requests through a WSGI server
using Daphne (or uvicorn) only for things WSGI cannot do, like WebSockets, HTTP long-polling or other IoT protocols
is possible, but entirely optional.

Related

Flask app stops after a few hours in windows [duplicate]

Setting up Flask with uWSGI and Nginx can be difficult. I tried following this DigitalOcean tutorial and still had trouble. Even with buildout scripts it takes time, and I need to write instructions to follow next time.
If I don't expect a lot of traffic, or the app is private, does it make sense to run it without uWSGI? Flask can listen to a port. Can Nginx just forward requests?
Does it make sense to not use Nginx either, just running bare Flask app on a port?
When you "run Flask" you are actually running Werkzeug's development WSGI server, and passing your Flask app as the WSGI callable.
The development server is not intended for use in production. It is not designed to be particularly efficient, stable, or secure. It does not support all the possible features of a HTTP server.
Replace the Werkzeug dev server with a production-ready WSGI server such as Gunicorn or uWSGI when moving to production, no matter where the app will be available.
The answer is similar for "should I use a web server". WSGI servers happen to have HTTP servers but they will not be as good as a dedicated production HTTP server (Nginx, Apache, etc.).
Flask documents how to deploy in various ways. Many hosting providers also have documentation about deploying Python or Flask.
First create the app:
import flask
app = flask.Flask(__name__)
Then set up the routes, and then when you want to start the app:
import gevent.pywsgi
app_server = gevent.pywsgi.WSGIServer((host, port), app)
app_server.serve_forever()
Call this script to run the application rather than having to tell gunicorn or uWSGI to run it.
I wanted the utility of Flask to build a web application, but had trouble composing it with other elements. I eventually found that gevent.pywsgi.WSGIServer was what I needed. After the call to app_server.serve_forever(), call app_server.stop() when to exit the application.
In my deployment, my application is listening on localhost:port using Flask and gevent, and then I have Nginx reverse-proxying HTTPS requests to it.
You definitely need something like a production WSGI server such as Gunicorn, because the development server of Flask is meant for ease of development without much configuration for fine-tuning and optimization.
Eg. Gunicorn has a variety of configurations depending on the use case you are trying to solve. But the development flask server does not have these capabilities. In addition, these development servers show their limitations as soon as you try to scale and handle more requests.
With respect to needing a reverse proxy server such as Nginx is concerned it depends on your use case.
If you are deploying your application behind the latest load balancer in AWS such as an application load balancer(NOT classic load balancer), that itself will suffice for most use cases. No need to take effort into setting up NGINX if you have that option.
The purpose of a reverse proxy is to handle slow clients, meaning clients which take time to send the request. These reverse load balancers buffer the requests till the entire request is got from the clients and send them async to Gunicorn. This improves the performance of your application considerably.

Django, FastAPI and DRF

I want to make a project, which uses Django as backend, PostgreSQL as database and FastAPI with Django REST Framework for REST.
Don't see any problems with making a project just with Django, DRF and Postgres, but face with difficulties when speak about FastAPI and DRF at the same time.
So there is no problem in connecting Postgres to Django, and there is no problem to make endpoints for DRF.
But how can I connect fastapi? Where to place endpoints and how to run all this stuff together?
In some examples I saw that FastAPI isntance is initiated in WSGI.py and then server runs from calling commands such like this:
uvicorn goatfish.wsgi:app
But i am not sure that it works like this when I mix more than only Django and FastAPI.
I want to use FastAPI for optical character recongnition and DRF for user registration, logins etc.
Are there any advices about making project with such a structure? Or maybe someone have a repository with such kind of project on github?
EDIT: Hope to see answers here, but for now I only see the solution in making classic Django + DRF app, then make FastAPI app with endpoints, run these apps on different ports and do some chain of actions:
From django app we load an image to form and when we submit this form we send POST request to FastAPI endpoint, which will run OCR process and then return JSON with recognized text and then will send this JSON to the Django Callback endpoint, which will process it and save to the database.
What do you think about such thing?
I think, you may:
Mix of fastapi+django. But this is only for replace DRF and use fastapi as rest framework.
Microservices. You may to run Django on one port, fastapi - another. And both may to use one shared database.
Mircoservices. All from point 2, but some api tasks (for example sign-in/sign-up) on Django and another - on fastapi.
As an alterantive you could use django ninja.
It uses similar concepts as FastAPI (Routes, Pydandantic Model Validation, Async Support) but is an Django app.
Which of course is more the monolithic approach but still valid.
Well, so after few days of thinking about I decided, that there is no sense in a question which I asked :)
Here we should talk about microservice architecture, where such kind of problem just doesn't exist. All we need is to make as much services as we need in our project using any framework (Django, FastAPI, Flask, Ruby etc.) and make connections between them.
As example I can run my main Django server on port 8000, my FastAPI server on port 5000 and my DRF service on port 6000. And then I can just do whatever I want from my main Django server making requests to endpoints of FastAPI and DRF.
So that's very simple example, now I'm diving deeper into microservice architecturing, but that's definitely what I need.

django channels vs daphene

I am little bit confused about the main roles of django-channels and uvicorn server. I have read a lot of blogs but did not get much clarification.
If we can implement an ASGI server for websockets using channels, then why do we need asgi server seperately like daphene or uvicorn?
Daphne is a ASGI server while Django Channels is an ASGI Framework for Django.
Links have been taken from www.uvicorn.org.
Also reference from another blog is mentioned below:
Channels was created to support asynchronous protocols like Websockets and long polling HTTP. Django applications still run synchronously. Channels is an official Django project but not part of core Django.
Django Async project will support writing Django applications with asynchronous code in addition to synchronous code. Async is a part of Django core.
Both were led by Andrew Goodwin.
These are independent projects in most cases. You can have a project that uses either or both. For example if you need to support a chat application over web sockets, then you can use Channels without using Django’s ASGI interface. On the other hand if you want to make an async function in a Django view, then you will have to wait for Django’s Async support for views.

How to use django-ddp

I'm using django as backend. While reading stuff about meteor, i found django-ddp.
I searched a lot, but I didn't get what django-ddp is for.
I understood that you can use it to connect meteor to your django backend, but what is the use case?
How does the client connect to django and/or meteor? Does meteor have to run on the same server? How are the http requests handled?
Maybe a tiny example would help me to get this.
For me important: Can i use this to combine benefits of django and meteor?
Django DDP provides a Meteor compatible, realtime, latency compensated backend framework for Django (Python) models. It can also serve your Meteor frontend code (HTML/JS/CSS/...) allowing you to avoid using Meteor (and node.js) on the server, whilst serving regular Django views at the same time.
Django is a respected web framework with a powerful object relational mapper (ORM), with support for schema migrations included by default. Django DDP is efficient and secure, using gevent to handle HTTP requests and manage concurrency at the process level, and multiple processes (across multiple hosts) to allow scaling-out to serve many clients simultaneously. WebSockets are handled using gevent-websocket. Combining these aspects with the realtime, latency compensated benefits of Meteor does indeed give you the advantages of both (unless you prefer to run node.js on your backend servers).
If Django DDP is used to serve your Meteor app then the client (browser) will connect to Django DDP automatically. Otherwise, you can connect your Meteor app to Django DDP and use the Django DDP connection like this:
if(Meteor.isClient) {
Django = DDP.connect('http://ddp.example.com/');
Tasks = new Mongo.Collection('myapp.Tasks', {connection: Django});
Django.subscribe('Tasks', {
onReady: function(error, result) {
// Log each matching Task to the browser console in a table
console.table(Tasks.find().fetch());
}
});
}
If you're serving your Meteor app from Django DDP then drop the DDP.connect line and omit the second parameter to new Mongo.Collection.
You might find the Todos example app a useful place to start. It includes a full working example of how to write both the Meteor client app and the Django DDP server app.
Disclaimer: I'm the author of Django DDP - sorry if parts of my answer sound like marketing guff but I'm just trying to answer the first part of the question.

Tornado and Django limitations?

here is what i've found when reading Tornado Help:
Tornado comes with limited support for WSGI. However, since WSGI does not support non-blocking requests, you cannot use any of the asynchronous/non-blocking features of Tornado in your application if you choose to use WSGI instead of Tornado’s HTTP server. Some of the features that are not available in WSGI applications: #tornado.web.asynchronous, the httpclient module, and the auth module.
what it was interresting "before" reading that is the "auth" module, it will make possible to access to Facebook or Google, it's like OpenID (?), but sadly it will not work on WSGI?!!! so how to make that thing work with Django? on FastCGI?
If you take a look at mixins in tornado.auth module you will see that it requires #asynchronous decorator, which is unavailable in WSGI mode due to synchronous nature of the protocol.
There was some kind of proposition to add asynchronous support to WSGI, but I believe it was not successful. Additional info on this:
http://mail.python.org/pipermail/web-sig/2008-May/003439.html
http://mail.python.org/pipermail/web-sig/2008-July/003545.html