祝!Django 3.0 リリース!
2019/12/02 Django 3.0がリリースされました。
Django 1.0がリリースされたのが2008年、2.0のリリースが2017年12月です。そして今年の12/2に3.0がリリースされました。
1から2へのバージョンアップが約10年かけたのに対して、2から3まで2年足らずという驚きのスピード感です。それに比べてこの2年間、私はいったい何をしていたのでしょうか?それではDjango 3.0で個人的に気になった新機能を見てみたいと思います!
ASGI supportとは
私はこれが気になりました。とは言ってもASGIというものを触ったことがなくて、これを公式サポートしました!と言われても、ほーん、という感じでした。でも俺にはWSGIさんがついているから・・・と。
しかし、調べてみるとどうやらASGIさんは無視できない存在っぽいようにだんだんと思えてきました。
リリースノートによると、現在、非同期機能はWSGIにはなくてASGIで実行された時のみサポートされているとあるし(でも将来的にはサポートするみたい?)。
ASGIの公式が言うには、「ASGIはWSGIのspiritual successor(精神的続編)」らしいですし。
こうしてみると私の強い味方に思えていたWSGIが、ASGIの下位互換なのではないかと思えてきました。
関係ないですけど、精神的続編って言葉、なんかカッコイイですね。ゼノギアスに対するゼノサーガ、ゴールデンアイ007に対するパーフェクトダーク等がそれに該当してくるみたいです。しかし、WSGIやASGIは別にゲームやフィクション作品って訳ではなく、続編という訳は果たして適しているだろうか?と思ったので精神的後継と読んでみようと思います。タイトルにもそう書きました。
ASGIでDjangoを動かしてみる
そうと決まれば話は早いってことで、試しにDjangoをASGIで動かしてみました。Dockerで環境を作って。
sudo docker run --rm -it -p 8000:8000 python:3.8 bash
python3.8を使います。ところでDjango 3.0はpython 3.6、3.7、および3.8をサポートしています。
pip install django daphne
django
と一緒にdaphne
もインストールします。daphne
はASGI
用のサーバみたいですね。WSGI
におけるuWSGI
がASGI
におけるdaphne
なのでしょう。きっと。
ちなみにdaphneはダフネと呼ぶらしいです。djangoはジャンゴなのに、daphneのdはちゃんと発音してもらえていいですね。
django-admin startproject app
cd app
daphne -b 0.0.0.0 -p 8000 app.asgi:application
インストールしたらプロジェクトを作って早速動かしてみます。
やった!動いた!完!
動いたけどこれだと何が嬉しいのかが分からない。まあ、当然ですよね。非同期機能が売りなのに同期通信しかしてないですし。
Djangoで非同期通信が試せるチャットアプリを構築するようなチュートリアルとかはないだろうか・・・
ありました。
https://channels.readthedocs.io/en/latest/tutorial/index.html
Django channelsが使うとDjangでweb socketが使えるみたいでして、ご丁寧にチャットアプリのチュートリアルがあります。これを写経して作ったチャットアプリをdaphneで動かしてみよう、という魂胆です。
しかし、Django channelsと今回のASGIサポートの関係性がイマイチよく分かってないです。まあ、でも使っているうちに分かってくるかもしれないので深入りしないでおきます。
ここにチュートリアルに沿って作った完成品をここに置いておきます。
ためしに動かしてみます。command: python manage.py runserver 0.0.0.0:8000
の状態です。
sudo docker-compose up -d
2窓で動作確認しましたが、ちゃんとチャットが使えますね。
では、これをdaphne
で動かしてみます。command
を次のように書き換えます。
services:
app:
build: .
- command: python manage.py runserver 0.0.0.0:8000
+ command: daphne -b 0.0.0.0 -p 8000 mysite.asgi:application
volumes:
- .:/srv
ports:
私の予想だとこれでも動くはずですが・・・。
sudo docker-compose down
sudo docker-compose up -d
なにやらエラーメッセージを読むとwebsocketは使えないって書いてありますね。
172.17.0.1:52480 - - [06/Dec/2019:07:36:28] "GET /chat/a/" 200 1413
172.17.0.1:52488 - - [06/Dec/2019:07:36:28] "WSCONNECTING /ws/chat/a/" - -
2019-12-06 07:36:29,471 ERROR Exception inside application: Django can only handle ASGI/HTTP connections, not websocket.
File "/usr/local/lib/python3.8/site-packages/daphne/cli.py", line 30, in asgi
await self.app(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/asgi.py", line 144, in __call__
raise ValueError(
Django can only handle ASGI/HTTP connections, not websocket.
172.17.0.1:52488 - - [06/Dec/2019:07:36:29] "WSDISCONNECT /ws/chat/a/" - -
asgi.pyの144行目付近を見てみましょう。
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']
)
HTTP connections以外だった時は例外を投げるようにしているみたいですね。これは一体どういうことでしょう。
- ASGI supportがまだweb socketに対応していない
- django channelsのチュートリアルのチャットアプリをDjango3.0を使って
daphne app.asgi:application
で動かそうとする考えがそもそも間違ってる
どっちかだと思ますが、良くはわかってません。謎は深まるばかりです。しかし、ASGIでDjangoを非同期対応できるというのは公式でも謳っていることではあるので、今後とも注視していこうと思います。
おわり
さよならWSGIさん。俺にはASGIさんがいるから・・・