概要
Cloud Functionsは2019/7時点でpythonのエミュレータがありません。それで最初に躓いたのが、関数へのパラメータの受渡をローカルでどうテストするかです。結果的に、Cloud Functions同様にFlaskのrequestオブジェクトを使うのが楽だったので、やり方をまとめます。
また、折角なのでFirestoreも含めて、ローカルでテストしてみます。
開発環境
- 開発環境
- MacOS
- python3.7
- pycharm
要約
やることは以下の通りです。
- テストしたい関数のソースを作る
- Flaskを使ってローカルにAPIを作る
- 2を実行して、localhostにリクエストを投げる
テストしたい関数
functions/getFilteredUser.py
import json
from google.cloud import firestore
# ソースはPt1と同じ
def get_filtered_user(request):
request_json = request.get_json()
if request.args and 'name' in request.args:
request_name = request.args.get('name')
elif request_json and 'name' in request_json:
request_name = request_json['name']
else:
request_name = ''
db = firestore.Client()
query = db.collection('user').where('name', '==', request_name)
docs = query.get()
users_list = []
for doc in docs:
users_list.append(doc.to_dict())
return_json = json.dumps({"users": users_list}, ensure_ascii=False)
return return_json
FlaskでローカルにAPI作成
localServer.py
from flask import Flask, request, abort, render_template, send_from_directory
# テストしたい関数を外部ソースからimport
from functions.getFilteredUser import get_filtered_user
app = Flask(__name__)
# methodにPOST等も指定(FlaskではデフォルトGETのみのため)
# '/~'がテストするときのパス
@app.route('/get-filtered-user', methods=['GET', 'POST'])
def local_api():
return get_filtered_user(request)
if __name__ == '__main__':
app.run()
Firestoreへのアクセス方法として、実行時に環境変数で秘密鍵ファイルを読み込ませています。localServer.pyを実行するとAPIが作られます。
POSTでリクエスト
$ curl -X POST -H "Content-Type: application/json" -d '{"name": "Alice"}' http://127.0.0.1:5000/get-filtered-user
{"users": [{"age": 19, "name": "Alice", "gender": "female"}]}
これで、Cloud Functionsにデプロイせずともテストできるようになりました。デプロイすると2分ほど待ちますが、この方法だとすぐにテストできます。
詳細版書きました
(2019/8/4) 詳細版書きました。良ければこちらも読んでみてください。
python×Cloud Functions×FirestoreでAPIを簡単に作ってみる Pt2 テスト編(詳細)