Kekeの日記

エンジニア、読書なんでも

表彰状ジェネレータをCloud Runを使ってgnuicorn + flaskでServerlessにホストする

f:id:bobchan1915:20190728005606p:plain

作ったサービス

私の会社ではzp-というプレフィクスをつけて、個人チャンネルを作ることができます。なんでも書くことできるのですが、いろんな友人がレスポンスをくれたりするので感謝を表したいと思い、メッセージ数やリアクション数からランキング付けをBotでしています。

しかし、ランキング上位の方にインセンティブがないので表彰状を生成するようにしたいと思い、表彰状を生成するAPIサーバーを作りました。表彰状時代はCloud Storageに格納されますので、そのURLが返ってきます。

POSTする情報は以下の通りです。

  • 相手の名前
  • Unipos付与Point
  • メッセージ数
  • リアクション数

適当に変えられるのですが、今回はこのような仕様になっています。その結果をそのURLを受け取ったランキングBotがチャンネルで投稿して以下のようにできます。

f:id:bobchan1915:20190728010941p:plain
投稿された表彰状

今週からは可読性の観点からフォントを変更しましたが、簡単に変更できます。

注意ですが、ホスト環境へのWrite権限がないためCloud Functionsでは今回のアプリケーションを作ることはできないのでCloud Runを使いました。

前提

FlaskやDjangoなどで記述したアプリケーションサーバーはどこかにホストしなければサービスとして使うことはできないです。

本番環境で使うにはGnuicornが使われます。Gunicornを使うことによりWebアプリケーションとWebサーバーを分離して考えることができます。

WSGIとは

Gunicornを使ってるので少しおさらいをします。

Web Server Gateway Interface(WSGI)とは以下のPEP3333で定義されたWebサーバーのインタフェースです。

www.python.org

かんたんなルールとしては

  • 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"}

開くと以下のようになっています。

f:id:bobchan1915:20190728011358p:plain
生成された表彰状

試しに自分の名前でやっていますが、いつもは感謝をし尽くせない友人の名前が入っており、毎週金曜日の16時にチャンネル投稿されます。