[PYTHON] I tried the asynchronous server of Django 3.0

Preface

maxresdefault.jpg

Django 3.0 was officially released 3 days ago. Release node link With so many changes, I'm very interested in the addition of support for ʻASGI`, I would like to actually use it. : sunny:

Note: What is ASGI ?: briefcase:

ASGI (Asynchronous Server Gateway Interface) is the spiritual successor to WSGI and aims to provide a standard interface between asynchronously enabled Python web servers, frameworks, and applications.

Whereas WSGI provided the standard for synchronous Python apps, ASGI provides both asynchronous and synchronous apps with a backward compatibility implementation of WSGI and multiple servers and application frameworks.

Document link

New project

Create a virtual environment for testing

 mkvirtualenv django3.0

Install Django

 pip3 install django

After the installation is complete, make sure you have Django 3.0

(django3.0) ~ $ pip3 list
Package    Version
---------- -------
asgiref    3.2.3  
Django     3.0    
pip        19.3.1 
pytz       2019.3 
setuptools 42.0.2 
sqlparse   0.3.0  
wheel      0.33.6

Let's create a new project and start a server

mkdir django-test
&&
django-admin startproject newtest
&&
cd newtest/
&&
python3 manage.py runserver

Let's access No. 8000 and you can see the familiar rocket.

UNADJUSTEDNONRAW_thumb_38.jpg So far Yoshi!: Relaxed :: point_up:

Let's take a look at the official documentation

2019-12-05 19.17のイメージ.jpg

How to deploy with ASGI¶
As well as WSGI, Django also supports deploying on ASGI, the emerging Python standard for asynchronous web servers and applications.

Django’s startproject management command sets up a default ASGI configuration for you, which you can tweak as needed for your project, and direct any ASGI-compliant application server to use.

Django includes getting-started documentation for the following ASGI servers:

How to use Django with Daphne
How to use Django with Uvicorn
The application object¶
Like WSGI, ASGI has you supply an application callable which the application server uses to communicate with your code. It’s commonly provided as an object named application in a Python module accessible to the server.

The startproject command creates a file <project_name>/asgi.py that contains such an application callable.

It’s not used by the development server (runserver), but can be used by any ASGI server either in development or in production.

ASGI servers usually take the path to the application callable as a string; for most Django projects, this will look like myproject.asgi:application.

Warning

While Django’s default ASGI handler will run all your code in a synchronous thread, if you choose to run your own async handler you must be aware of async-safety.

Do not call blocking synchronous functions or libraries in any async code. Django prevents you from doing this with the parts of Django that are not async-safe, but the same may not be true of third-party apps or Python libraries.

Configuring the settings module¶
When the ASGI server loads your application, Django needs to import the settings module — that’s where your entire application is defined.

Django uses the DJANGO_SETTINGS_MODULE environment variable to locate the appropriate settings module. It must contain the dotted path to the settings module. You can use a different value for development and production; it all depends on how you organize your settings.

If this variable isn’t set, the default asgi.py sets it to mysite.settings, where mysite is the name of your project.

Applying ASGI middleware¶
To apply ASGI middleware, or to embed Django in another ASGI application, you can wrap Django’s application object in the asgi.py file. For example:

from some_asgi_library import AmazingMiddleware
application = AmazingMiddleware(application)

Link

Roughly summarized

--Do not start the server with python manage.py runserver, it will start the usual wsgi server. --It is recommended to use Daphne or ʻUvicorn` when starting the server.

Let's open the official link to see what Daphne is link

How to use Django with Daphne¶
Daphne is a pure-Python ASGI server for UNIX, maintained by members of the Django project. It acts as the reference server for ASGI.

Installing Daphne¶
You can install Daphne with pip:

python -m pip install daphne
Running Django in Daphne¶
When Daphne is installed, a daphne command is available which starts the Daphne server process. At its simplest, Daphne needs to be called with the location of a module containing an ASGI application object, followed by what the application is called (separated by a colon).

For a typical Django project, invoking Daphne would look like:

daphne myproject.asgi:application
This will start one process listening on 127.0.0.1:8000. It requires that your project be on the Python path; to ensure that run this command from the same directory as your manage.py file.

Translated --Install daphne with pip --Run daphne myproject.asgi: application to start ASGI server --Access to 127.0.0.1.8000

Let's try: point_up:

Start ASGI server

daphne installation

 pip3 install daphne

Server startup

daphne [Project name].asgi:application

When I accessed 8000, I could see the rocket again, although the characters have changed a little. : eye:

2019-12-05 19.59のイメージ.jpg

WebSocket test

I will open a browser and send a websocket message. UNADJUSTEDNONRAW_mini_3b.jpg

500 is returned, the error message is as follows.

2019-12-05 11:02:09,533 ERROR    Exception inside application: Django can only handle ASGI/HTTP connections, not websocket.
  File "/Envs/django3.0/lib/python3.7/site-packages/daphne/cli.py", line 30, in asgi
    await self.app(scope, receive, send)
  File "/Envs/django3.0/lib/python3.7/site-packages/django/core/handlers/asgi.py", line 146, in __call__
    % scope['type']
  Django can only handle ASGI/HTTP connections, not websocket.

There seems to be something in line 146 of ʻasgi.py`, let's take a look.

asgi.py



 async def __call__(self, scope, receive, send):
        """
        Async entrypoint - parses the request and hands off to get_response.
        """
        # Serve only HTTP connections.
        # FIXME: Allow to override this.
        if scope['type'] != 'http':
            raise ValueError(
                'Django can only handle ASGI/HTTP connections, not %s.'
                % scope['type']
            )
        # Receive the HTTP request body as a stream object.
        try:
            body_file = await self.read_body(receive)
        except RequestAborted:
            return
        # Request is complete and can be served.
        set_script_prefix(self.get_script_prefix(scope))

Notice the two-line comment below.

 # Serve only HTTP connections.
 # FIXME: Allow to override this.

At the moment, only http communication is allowed. Please fix it yourself if necessary!

last

The possible causes are as follows.

--Maybe I don't know about Django again --ASGI communication is realized by other means instead of Websocket --Full support for ASGI is yet to come

Current Django 3.0, if you want to use websocket, we recommend using the django-channel package.

Recommended Posts

I tried the asynchronous server of Django 3.0
I tried Django
I tried cluster analysis of the weather map
I tried to touch the API of ebay
I tried to correct the keystone of the image
I checked the session retention period of django
I tried using the image filter of OpenCV
I tried to predict the price of ETF
I tried to vectorize the lyrics of Hinatazaka46!
I tried to summarize the settings for various databases of Django (MySQL, PostgreSQL)
I tried to summarize the basic form of GPLVM
I tried the MNIST tutorial for beginners of tensorflow.
I tried the changefinder library!
I tried using the API of the salmon data project
I tried to visualize the spacha information of VTuber
I tried to erase the negative part of Meros
I tried scraping the advertisement of the pirated cartoon site
I tried the simplest method of multi-label document classification
I tried to classify the voices of voice actors
I tried running the sample code of the Ansible module
I tried to summarize the string operations of Python
I tried to find the entropy of the image with python
[Horse Racing] I tried to quantify the strength of racehorses
I tried "gamma correction" of the image with Python + OpenCV
I tried to get the location information of Odakyu Bus
I participated in the translation activity of Django official documents
I tried the accuracy of three Stirling's approximations in python
I tried to find the average of the sequence with TensorFlow
I tried starting Django's server with VScode instead of Pycharm
I tried refactoring the CNN model of TensorFlow using TF-Slim
I tried face recognition of the laughter problem using Keras.
I tried morphological analysis of the general review of Kusoge of the Year
[Python] I tried to visualize the follow relationship of Twitter
I found the cause of mysterious communication of Minecraft server (Spigot)
I tried a little bit of the behavior of the zip function
[Machine learning] I tried to summarize the theory of Adaboost
[Python] I tried collecting data using the API of wikipedia
I tried to fight the Local Minimum of Goldstein-Price Function
I displayed the chat of YouTube Live and tried playing
I tried to output the access log to the server using Node.js
I tried the TensorFlow tutorial 1st
I tried the Naro novel API 2
I investigated the mechanism of flask-login!
I tried using GrabCut of OpenCV
I tried the TensorFlow tutorial 2nd
I tried the Naruro novel API
The meaning of ".object" in Django
The story of remounting the application server
I tried to move the ball
I tried using the checkio API
I tried asynchronous processing using asyncio
I tried to estimate the interval.
I tried to rewrite the WEB server of the normal Linux programming 1st edition with C ++ 14
I tried scraping the ranking of Qiita Advent Calendar with Python
[Linux] I tried to summarize the command of resource confirmation system
I tried to get the index of the list using the enumerate function
I tried to automate the watering of the planter with Raspberry Pi
Flow of getting the result of asynchronous processing using Django and Celery
I tried to build the SD boot image of LicheePi Nano
I looked at the meta information of BigQuery & tried using it
I tried sending an email from the Sakura server with flask-mail