表彰状ジェネレータをCloud Runを使ってgnuicorn + flaskでServerlessにホストする
作ったサービス
私の会社ではzp-
というプレフィクスをつけて、個人チャンネルを作ることができます。なんでも書くことできるのですが、いろんな友人がレスポンスをくれたりするので感謝を表したいと思い、メッセージ数やリアクション数からランキング付けをBotでしています。
しかし、ランキング上位の方にインセンティブがないので表彰状を生成するようにしたいと思い、表彰状を生成するAPIサーバーを作りました。表彰状時代はCloud Storageに格納されますので、そのURLが返ってきます。
POSTする情報は以下の通りです。
- 相手の名前
- Unipos付与Point
- メッセージ数
- リアクション数
適当に変えられるのですが、今回はこのような仕様になっています。その結果をそのURLを受け取ったランキングBotがチャンネルで投稿して以下のようにできます。
今週からは可読性の観点からフォントを変更しましたが、簡単に変更できます。
注意ですが、ホスト環境へのWrite権限がないためCloud Functionsでは今回のアプリケーションを作ることはできないのでCloud Runを使いました。
前提
FlaskやDjangoなどで記述したアプリケーションサーバーはどこかにホストしなければサービスとして使うことはできないです。
本番環境で使うにはGnuicornが使われます。Gunicornを使うことによりWebアプリケーションとWebサーバーを分離して考えることができます。
WSGIとは
Gunicornを使ってるので少しおさらいをします。
Web Server Gateway Interface(WSGI)とは以下のPEP3333で定義されたWebサーバーのインタフェースです。
かんたんなルールとしては
- 2つの引数を持った呼び出し可能なオブジェクトであるということ
- 第2引数であるレスポンスに対してHTTPステータスコードとヘッダー情報を渡すこと
- レスポンスボディとしてバイト文字列をiterableなオブジェクトで返すこと
です。PythonのWebフレームワークもWSGIとい仕様に則って開発がされているため、特に意識をする必要はありません。
Dockerfile
以下が今回のFlaskアプリケーションをGnuicornで実行するDockerfileです。
FROM python:3.7 ENV APP_HOME /app WORKDIR $APP_HOME COPY . . RUN pip install -r requirements.txt CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 app:app
これをDeployして実行できます。
呼び出し
以下のようなリクエストを送ります。
$ curl -X POST -H "Content-Type:application/json" $UNIPOS_HOST -d '{"name":"KeisukeYamashita", "uniposCount": 10, "messageCount": 30, "reactionCount": 20}'
すると以下のようなURLが返ってくるので、これが表彰状になっています。
{"image_url":"https://storage.googleapis.com/MASK_MASK_MASK.png"}
開くと以下のようになっています。
試しに自分の名前でやっていますが、いつもは感謝をし尽くせない友人の名前が入っており、毎週金曜日の16時にチャンネル投稿されます。