引き続き Python 非同期プログラミングを学習していきましょう。ここでは非同期 Web フレームワーク sanic を紹介します。なぜ tornado ではないのでしょうか? フレームワークの使いやすさの点では、Flask は Tornado よりもはるかにシンプルですが、残念ながら flask は非同期をサポートしておらず、sanic は Flask 構文に似た非同期フレームワークです。
github:GitHub - sanic-org/sanic: Web アプリ開発を加速する | 素早く構築しましょう。速く走る。
ただし、sanic には環境に関する要件があります。
- macOS/Linux
- Python 3.6+
しかし、macOSにsanicをインストールするときに、やはりピットを踏んでしまいました。依存ライブラリの
ujson
インストールに失敗しています。結局、公式の Python をアンインストールし、miniconda (いくつかの追加ツールを統合するサードパーティの Python インストール パッケージ) をインストールする必要がありました。
サニックをインストールする
> pip3 install sanic
健全な開発の最初の例
公式の最初の例を書きますhello.py
。
from sanic import Sanic
from sanic.response import json
from sanic.exceptions import NotFound
app = Sanic(name="pyapp")
@app.route('/')
async def test(request):
return json({'hello': 'world'})
if __name__ == '__main__':
app.error_handler.add(
NotFound,
lambda r, e: sanic.response.empty(status=404)
)
app.run(host='0.0.0.0', port=8000)
上記のプログラムを実行します。
> python3 hello.py
[2020-04-21 23:12:02 +0800] [18487] [INFO] Goin Fast @ http://0.0.0.0:8000
[2020-04-21 23:12:02 +0800] [18487] [INFO] Starting worker [18487]
ブラウザ経由でアクセス:http://localhost:8000/
リクエストブロック
上の例では、test()
ビュー関数の処理に 5 秒かかると仮定すると、リクエストはブロックされます。
……
from time import sleep
app = Sanic(name="pyapp")
@app.route('/')
async def test(request):
sleep(5)
return json({'hello': 'world'})
……
サービスを再起動し、ブラウザ経由でリクエストを送信します。リクエストには 5 秒かかることがわかりました。これはユーザーにとって明らかに耐えられない時間です。
非同期ノンブロッキング
したがって、非同期呼び出しを実装する必要があります。変更された完全なコードは次のとおりです。
import asyncio
from sanic import Sanic
from sanic.response import json
from sanic.exceptions import NotFound
from time import sleep, ctime
app = Sanic(name="pyapp")
async def task_sleep():
print('sleep before', ctime())
await asyncio.sleep(5)
print('sleep after', ctime())
@app.route('/')
async def test(request):
myLoop = request.app.loop
myLoop.create_task(task_sleep())
return json({'hello': 'world'})
if __name__ == '__main__':
app.error_handler.add(
NotFound,
lambda r, e: sanic.response.empty(status=404)
)
app.run(host='0.0.0.0', port=8000)
Pythonの非同期の利用については前回の記事を参考にサービスを再起動してください。今度はフロントエンドの詰まりがなくなりました。
sanic の実行ログを見ると、次のようになります。
[2020-04-21 23:43:14 +0800] - (sanic.access)[INFO][127.0.0.1:57521]: GET http://localhost:8000/ 200 17
sleep before Tue Apr 21 23:43:14 2020
sleep after Tue Apr 21 23:43:19 2020
test()
まだ実行中ですが、ビュー関数の応答はブロックされません。
考え方: 私の要求が次のようなものである場合: リクエストが処理された後、それが処理されたことを私に伝え、それからサイレントに処理し、処理されたときに処理の結果を率先して伝えてください。この場合、WebSocket を使用する必要があります。
テストを受けている友達が参加してコミュニケーションをとることができ、グループは学習資料や面接の質問、プロジェクトの履歴書などを多数まとめています。