人工衛星の回帰日数計算をGoogle Cloud Function化
背景
先日作った「人工衛星の回帰日数を計算するツール*1」を、Google Cloud Function化してみました。参考にしたのは、日本語のブログ記事*2と、Google Cloud Functionのドキュメント*3です。
Cloud Functionというのは、関数呼び出し的にGoogle Cloudを使うサービスで、仮想マシンやWebサーバーを用意しなくても、比較的軽い単発の処理を、HTTPリクエスト等で呼び出すことができます。
当方にとって一番うれしいのは、無料で使えることです。つまり、Google Cloud Platformの無料枠内で月に200万回呼び出し可能なことです*4。
結果
下記が、回帰日数計算をCloud Functionとして利用するためのフォームです。
上記で人工衛星のTLEと日時を入力して、「Search Repeat Cycle」ボタンを押すと、例えば下記のような回帰日数計算結果が表示されます。
苦労した点
データがCloud Functionに渡らない
問題
Cloud Functionは初めてのため、HTMLフォームからCloud Functionにデータ(TLEとdate)が渡せず、非常に苦労しました。Cloud Functionのページに書かれたテスト実行ではデータが渡るのですが、HTMLフォームからは渡らないというもの。
仮解決策
ChromeのDevToolのNetworkで調べたところ、データ自体はちゃんと送られている模様。また、手でURLを修正し、データをURLに直接埋め込むと、上手く行きます(例えば「URL?date=2018-09-17%2011:00:00」等)。
少し調べたところ、formのmethodとして、POSTの代わりにGETを使えば、データがURLに埋め込まれるため、上手く行く模様*6。しかし、GETでは、データが長いとURLが長くなりすぎて、上手く行かない場合があるようです。また、ネットワーク上を生データが流れるので、お勧めできないようです。
本解決策に向けて
そこで、Cloud Functionの関数内に渡される引数「request」からデータを取り出す方法を工夫すれば良いのですが、これも、Cloud Functionのページに書かれたテストでは上手く行くものの、HTMLフォームからPOSTした場合は、値がうまく渡りません。
解決策
Webで、Cloud Function (Python版)の色々な使用例を調べたのですが、結局分からず、Cloud Functionのインターフェースとして使っているFlaskのドキュメントを調べることにより、解決することができました。コードとしては、下記の部分で、特に、request.formを使った部分は、Webでの記載例が見つかりませんでした。POSTで渡されるデータを受け取るには、この部分が必須でした。
request_json = request.get_json() if request.args: if 'TLE' in request.args: TLE = request.args.get('TLE') if 'date' in request.args: date = request.args.get('date') elif request_json: if 'TLE' in request_json: TLE = request_json['TLE'] if 'date' in request_json: date = request_json['date'] else: if 'TLE' in request.form: TLE = request.form['TLE'] if 'date' in request.form: date = request.form['date']
計算結果が改行無しで表示される
問題
上記で、計算結果が表示されるようになったものの、結果が改行無しで表示されるため、非常に読みにくくなりました。
解決策
これに関しても、Flaskのドキュメントを調べることにより解決しました。Cloud Functionの戻り値として単に文字列を返す場合、結果のmimetypeが自動的にhtmlになるが原因でした。そこで、下記の様に、mimetypeを指定してResponseオブジェクトを返すことで、上手く表示されるようになりました。
return Response(text, mimetype='text/plain')