PONCOTSU

インフラ領域を主にあれしてます

Windows開発機では functions-framework-pythonのローカルエミュレータを動かせない

Cloud Functionsをそれなりに利用するようになると、動かす関数の信頼性・安全性を向上させる、あるいは開発体験を向上させるためにユニットテストをしっかり書くようにする・CIを回すようにするといった段階に進むことが多々あると思います。 そこで活用したいローカルエミュレータなのですが、Python製ライブラリだとWindowsを使う開発者を対象としておらず、開発環境を整えることが不可能だったよ、という話です。

要約

  1. GCP公式がCloud Functionsのローカルエミュレータを配布している
  2. PythonエミュレータWindows機では動かすことができない
  3. 回避策は「テスト対象を絞る」「別の言語でCloud Functionsで動かす関数を実装しなおす」

Cloud Functionsのローカル開発環境に利用するfunctions-frameworkシリーズ

Cloud Functionsを使ったサーバレスアーキテクチャを採用する際、ローカルで事前に検証・ユニットテストなどに活用するように、公式からCloud Functionsのエミュレータが配布されています。 今回はこのPythonで書かれたエミュレータfunctions-framework-python)はWindowsでは動かせられないよ、という趣旨の話です。 なおPythonの他にNode.js・JavaRubyでも同様のライブラリが開発されています。

本題

PythonエミュレータWindows機では動かすことができない

Pythonで書かれたエミュレータfunctions-framework-python)は、内部で Flask が使われています。 Flask とはPythonで書かれたウェブサーバで、他の言語でいうところの Sinatra(Ruby) express.js(Node.js) にあたるウェブフレームワークです(少し語弊ありそう)。 エミュレータでは Flask を動かすためのアプリケーションサーバgunicorn というライブラリを利用しており、この gunicorn が曲者で、unix系OSでしか動かせないライブラリとして開発されていたのです。
なのでWindowsでは gunicorn を動かそうにも動かすことができず、連鎖して Flask が動かず、当然 functions-framework-python も動かないという構造になっていました。

なお、厳密にはpipインストールすらできずつまづく、というところでその先進めない状態になります。

# Windows機でpip installしようとすると...
pipenv install --dev
Installing dependencies from Pipfile.lock (12c19b)...
  ================================ 1/1 - 00:00:00
Ignoring gunicorn: markers 'platform_system != "Windows"' don't match your environment

Stackoverflowでも「そもそもgunicornはWindows用に作られていないよ」というやりとりが...w stackoverflow.com

回避策

さて、課題があっても解決しなければならない・解決するのがエンジニアリング。
採用したいかどうかは置いておいて、採れる回避策を検討しました。

1. テスト対象を絞る

そもそもローカルエミュレータを使いたい理由は主に以下の2点です。

  • ローカルで動作確認をとりたい(HTTPトリガーの関数の場合)
  • CI等で動作確認をとりたい

逆に言うと、ローカルで動作確認をとらないと決めたならエミュレータは不要です。特にPub/Sub経由のイベントトリガーの関数としてCloud Functionsを利用する場合、以下の理由でローカルでの動作確認がしづらかったりします。

  • 最初に実行するmain関数の部分で返り値が不要だったりするので、動作確認がしづらい
  • 同様の理由でユニットテストも書きづらい
  • Pub/Sub側のエミュレータを用意する必要がありかなり環境構築がつらくなる

上記理由からmain関数から呼ぶ独自の関数やクラスの振る舞いを単体テストする、などの対応で納めることが可能な作りならば、「エミュレータは不要」と判断することもできます。

2. コンテナで隠蔽してあげる

Pythonを動かす環境自体をDockerコンテナで隔離してあげれば、WindowsだろうがMacだろうがコンテナの中は同じ環境として扱えるのでこの問題は解消されます。
しかし、開発者にDockerに関する知識・Python特有の仮想環境の知識が求められるようになるため、「関数を書くことだけに集中」という状態はより作りづらくなるなぁという課題も生まれます。

3. 別の言語でCloud Functionsで動かす関数を実装しなおす

いやどうしてもローカルエミュレータで動作確認したいんだ!ということでしたら、やはりWindowsでも環境構築できる言語で再実装・再構築し直す必要があります。 Windowsでも相性がよさそうなのはJavaや.NETなんですかね。試してないのでわからないです。

さいごに

Cloud Functionsに限らずサーバレス関数な技術は使い勝手がよくてとても便利なのですが、テストを書いたり、開発者が同じ開発環境を整える手筈を組もうとすると結構大変です。無邪気にアプリケーションでの利用をするのはなるべく避けるのも運用観点では重要な判断軸なのかなと思ったり。