ResponderをUvicornやGunicornでデプロイする方法

はじめに

PythonのWebフレームワークと言えば、フルスタックならDjangoで軽量ならFlaskというのが一般的になりつつあると思います。

そんな中で最近話題にあがっているのがResponderです。
Flaskとの一番の違いはASGIアプリケーションであるという点でしょうか。 つまり、非同期処理を簡単に実装することができます。

Responderの具体的な使い方は既にまとめてくださっている方がいるので割愛します。
(大変助かっています) blog.ikedaosushi.com qiita.com

Flaskを使ってプロダクション環境に公開する場合には、GunicornやuWSGIなどのWSGIサーバを使うことが多いと思います。
そこで、Responderの場合にはどうすれば良いか簡単に紹介します。

コード例

以降は以下のコードを実行して試しています。

# app.py

import responder

api = responder.API()

@api.route("/{greeting}")
async def greet_world(req, resp, *, greeting):
    resp.text = f"{greeting}, world!"

if __name__ == '__main__':
    api.run()

開発環境の場合はそのままpythonで実行するだけで問題ありません。

python app.py

http://127.0.0.1:5042/hello にアクセスすると、hello, world!と表示されます。

Uvicorn

ResponderはビルトインサーバとしてUvicornを採用しています。
実際、python app.pyを実行した際にUvicornが起動しているのがわかります。

INFO: Started server process [22205]
INFO: Waiting for application startup.
INFO: Uvicorn running on http://127.0.0.1:5042 (Press CTRL+C to quit)

そのため、特に何もする必要がないとも言えますが、以下のように実行することもできます。

uvicorn app:api

ポートは変わっていますが、問題なく起動できています。

INFO: Started server process [22461]
INFO: Waiting for application startup.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

このとき、デバッグオプションを付けると、ファイル変更を検知して、自動でリロードしてくれます。

uvicorn app:api --debug

Gunicorn

UvicornでデプロイできるのでGunicornは不要説もありますが、Uvicornは複数ワーカーの起動ができないので、複数ワーカーで起動させるためにもGunicornを使いたいという思いがあります。

Uvicornの公式サイトにしっかりと載っていました。 www.uvicorn.org

Gunicornの設定にworker_classというオプションがあるようで、ここでUvicornクラスを指定すれば良さそうです。 docs.gunicorn.org

というわけで、Gunicornをインストールした後で、以下のように実行します。

gunicorn -k uvicorn.workers.UvicornWorker app:api

Gunicornで起動できています。

[22712] [INFO] Starting gunicorn 19.9.0
[22712] [INFO] Listening at: http://127.0.0.1:8000 (22712)
[22712] [INFO] Using worker: uvicorn.workers.UvicornWorker
[22715] [INFO] Booting worker with pid: 22715
[22715] [INFO] Started server process [22715]
[22715] [INFO] Waiting for application startup.

これまでFlask+Gunicorn+Nginx+Systemdな環境で動作するアプリケーションがあったとして、とある事情でFlaskからResponderへの移行を考えないといけなくなったとします。

Gunicornを使っている場合おそらくconfigファイルに色々な設定を書いていると思います。
そこに、1行だけworker_classの指定を書き加えて、FlaskからResponderのアプリケーションに差し替えるだけで、それ以外の設定はそのままで動作するはずです。

おわりに

Responderは新しいWebフレームワークなのでまだ発展途上であり、ドキュメントもかなり少ないですが、非同期処理を簡単に実装できるのは魅力的です。

そんな中、これまで通りGunicornでデプロイする方法を紹介しました。

間違い等ありましたら指摘していただけると幸いです。