はじめに
BigQuery に溜まったデータに対して Python のロジックをかまして、画像を返したいというケースがあったので、 Google Cloud Functions で実現できるか検証しました。自分の欲しいところまではできたので、記事としてまとめておきます。
GitHub でソースコード公開してますので、そちらも合わせてご参照ください。
https://github.com/tanabee/functions-matplotlib
最小限の実装
以下のコードで動作する。 Cloud Functions の動作環境にはデフォルトで Flask がインストールされているので、 Flask の記法で HTTP リクエストを処理できる。 matplotlib は別でインストールする必要があるので、 requirements.txt に記載。
Cloud Functions のローカル環境での開発〜デプロイは以下を参照。
Google Cloud Functions のプログラムを Mac のローカル環境で開発〜デプロイする
from flask import make_response
import matplotlib.pyplot
from matplotlib.backends.backend_agg import FigureCanvasAgg
from io import BytesIO
import random
def graph(request):
# グラフ生成部分
fig, ax = matplotlib.pyplot.subplots()
ax.set_title(u'GRAPH')
x_ax = range(1, 200)
y_ax = [x * random.randint(100, 200) for x in x_ax]
ax.plot(x_ax, y_ax)
canvas = FigureCanvasAgg(fig)
buf = BytesIO()
canvas.print_png(buf)
data = buf.getvalue()
response = make_response(data)
response.headers['Content-Type'] = 'image/png'
response.headers['Content-Length'] = len(data)
return response
matplotlib
ソースコード: https://github.com/tanabee/functions-matplotlib/tree/f27e307e5044d0a236b47c44576e82fa1f9be05d
トークンで簡易認証
トークンを使って認証をしてみる。 Cloud Functions の環境変数を使って認証している。これにより [URL]?token=[環境変数で設定したトークン]
のようにリクエストしないと 403 エラーを返すようになる。
- from flask import make_response
+ from flask import make_response, abort
import matplotlib.pyplot
from matplotlib.backends.backend_agg import FigureCanvasAgg
from io import BytesIO
import random
+ import os
def graph(request):
+ if request.args.get('token') != os.environ.get('TOKEN', 'token123'):
+ return abort(403)
+
fig, ax = matplotlib.pyplot.subplots()
TOKEN はオレンジ枠で囲った部分で設定できる。デプロイコマンド時に設定することも可能。
まとめ
matplotlib で生成した画像を Cloud Functions を使って、 HTTP リクエストで返せるようにできました。公開範囲を絞りたい場合には、簡易なトークンも実装できます。 Cloud Functions は無料枠も多くて、簡単に実装できるので良いですね。
以上!