Cloud Functionsをローカル環境で動かせるFunction Frameworkを試してみた

2021.12.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

MAD事業部の小倉@大阪オフィスです。

本エントリは クラスメソッド Google Cloud Advent Calendar 2021 の 3日目の記事です。

Google Cloud学習のとっかかりとして、Cloud Functionsを試しています。 その中でドキュメントに紹介されていたFunction Frameworkについて試してみました。

Function Frameworkとは

Function Frameworkを使うと、Cloud Functionで実行する関数をローカルで実行することが出来ます。

やってみる

Function Frameworkは様々な言語で用意されています。

都合(私の好み)により、今回はPython版を使い、ReadMeにある例を試してみます。

(※追記) 尚、以降の手順は以下の環境で実施しました。

環境 バージョン
OS macOS Mojave(10.14.6)
Python 3.9.9
Function Framework 3.0.0

インストール

pip install functions-fraemwork

インストールはこれだけです。あら簡単。

ローカルでHTTP関数(Hello World)の実行

main.py ファイル内に以下のコードを記述し、

def hello(request):
    return "Hello world!"
functions-framework --target=hello

を実行します。

ターミナルをそのままに、ブラウザからhttp://localhost:8080 にアクセスすると、Hello world! が表示されるのが確認できます。ローカルで実行できているようですね。

「あれ、どうしてmain.pyを識別しているんだ?」と思ったのですが、

  • --source で呼び出すファイルを指定。デフォルトはカレントディレクトリのmain.py
  • --target で呼び出す関数名を指定。デフォルトはfunction

とのことで、どうやらデフォルトでmain.pyを参照するようです。 また、

  • --signature-type で関数のタイプを指定。デフォルトはhttp。他にevent,cloudeventが指定可能

とあるので、先程の呼び出しはHTTP関数呼び出しになっています。 (その他のパラメータについてはGitHubのREADMEを参照してください)

ローカルでイベントドリブン関数の実行

次はイベントドリブンで関数を実行します。 main.pyに以下を記述します。

def hello(event, context):
     print("Received", context.event_id)

1つ目のターミナルで、この関数をfunction frameworkでイベントタイプ指定で実行しておきます。

functions-framework --target=hello --signature-type=event --debug --port=8080

次に別のターミナルからPub/Subのエミュレータを起動します。 最初に以下のコマンドでインストールします。

gcloud components install pubsub-emulator
gcloud components update

公式でエミュレータが用意されているのはありがたいですね。(Pub/Sub以外のエミュレータは以下を参照してください)
gcloud beta emulators

環境変数PUBSUB_PROJECT_ID を指定しつつ、エミュレータを(先程の関数とは別ポートで)起動します。

export PUBSUB_PROJECT_ID=my-project
gcloud beta emulators pubsub start \
    --project=$PUBSUB_PROJECT_ID \
    --host-port=localhost:8085

さらに別のターミナルから、エミュレータのPub/Subに対して

  • Pub/Subトピックの作成
  • サブスクリプションの作成
  • トピックへメッセージをPublish

をやっていきます。

先ず、以下の環境変数を設定します。

export PUBSUB_PROJECT_ID=my-project
export TOPIC_ID=my-topic
export PUSH_SUBSCRIPTION_ID=my-subscription

次に、アプリケーションがエミュレータを見に行く為の環境変数を設定します。

gcloud beta emulators pubsub env-init
[/shell/]
を実行すると、`export PUBSUB_EMULATOR_HOST=localhost:8085` がターミナルに出力されたので、これを実行するか、


$(gcloud beta emulators pubsub env-init)

を実行して直接設定します。

最後にエミュレータのPub/Subに対して操作します。 以下のリポジトリにあるスクリプトを使って各操作を実行します。

git clone https://github.com/googleapis/python-pubsub.git
cd python-pubsub/samples/snippets/
pip install -r requirements.txt
# トピック作成
python publisher.py $PUBSUB_PROJECT_ID create $TOPIC_ID
# サブスクリプション作成
python subscriber.py $PUBSUB_PROJECT_ID create-push $TOPIC_ID $PUSH_SUBSCRIPTION_ID http://localhost:8080
# トピックへ発行
python publisher.py $PUBSUB_PROJECT_ID publish $TOPIC_ID

ターミナルからPub/Subを介して関数が実行されている様子が確認できました。

まとめ

Function FrameworkでCloud Functionsをローカルで実行してみました。 Function Frameworkは他にも機能がありますので、気になる方はドキュメント、GitHub等を参照ください。

ローカルでCloud Functionを操作させる環境がpip install でサッと作れるのは嬉しいですね。公式でエミュレータがあるのもありがたいポイントです。 引き続きGoogle Cloudの学習を進めていこうと思います。

明日 12/4 は 新井成一 さんです。よろしくお願いします!

参考