GAEへpythonとFirestoreを使ったサービスをデプロイする
はじめに
Python3.7のruntimeがGAE standard environmentで使えるようになったため、flaskでアプリを作ってGAEへデプロイしている。DBにDatastoreとFirestoreが選択肢に入ってくるが、GoogleがFirestoreが後継だと強く言っているようなので、今回はこちらを選択した。
開発環境の設定
- GCPのコンソール上でFirebaseをenableにする
- gcloudコマンドのインストール
- サービスアカウントJSON fileをダウンロードし、
GOOGLE_APPLICATION_CREDENTIALS
へ割り当てる
FirebaseのサービスアカウントのJSONファイルはここから手に入れることができる。
$ curl https://sdk.cloud.google.com | bash $ exec -l $SHELL $ gcloud init $ export GOOGLE_APPLICATION_CREDENTIALS=path/to/creds.json
サービスの実装
準備するファイルは下記。
- requirements.txt
: dependenciesを宣言
- main.py
: アプリのソースコード
- app.yaml
: GAEへのデプロイ用
まずはrequirements.txt
。google-cloud-firestore
をあえて入れる理由はpipのバグがあるかららしい。本来はfirebase-admin
だけで十分とのこと。
Flask==1.0.2 firebase-admin==2.13.0 google-cloud-firestore==0.29.0
次にmain.py
。Firebase Admin SDKでクライアントを作っている。
import firebase_admin import flask from firebase_admin import firestore from flask import request app = flask.Flask(__name__) firebase_admin.initialize_app() SUPERHEROES = firestore.client().collection('superheroes') @app.route('/', methods=['GET']) def index(): return """ <h1> Create hero? </h1> <form method="post" action='/heroes'> <input type="text" size="30" name="hero name"> <input type="submit" value="create hero"> </form> <h1> Read hero? </h1> <form method="post" action='/read'> <input type="text" size="30"name="id"> <input type="submit" value="read hero"> </form> """ @app.route('/heroes', methods=['POST']) def create_hero(): req = {"name": request.form['hero name']} hero = SUPERHEROES.document() hero.set(req) return """ <h1> id': %s </h1> <form method="get" action='/'> <input type="submit" size="30" value="back to the index"> </form> """ % hero.id @app.route('/read', methods=['POST']) def read_hero(): id = request.form['id'] heroname = _ensure_hero(id).to_dict() return """ <h1> hero is %s </h1> <form method="get" action='/'> <input type="submit" value="back to the index"> </form> """ % heroname['name'] def _ensure_hero(id): try: return SUPERHEROES.document(id).get() except: flask.abort(404) if __name__ == '__main__': app.run(host='127.0.0.1', port=8080, debug=True)
最後にapp.yaml
。runtimeにpython3.7を指定。
runtime: python37 service: heroe
GAEへのデプロイと動作の確認
GAEへのデプロイはgcloud app deploy
で行う。
Beginning deployment of service [heroes]... ╔════════════════════════════════════════════════════════════╗ ╠═ Uploading 1 files to Google Cloud Storage ═╣ ╚════════════════════════════════════════════════════════════╝ File upload done. Updating service [heroes]...done. Setting traffic split for service [heroes]...done. Deployed service [heroes] to [https://heroes-dot-my-project.appspot.com]
ヒーローの名前を入力すると、Firestore上で割り当てられたid
が返ってくる。
知っているidを入力すると、ヒーローの名前を知ることができる。
まとめ
GAEからFirestoreを使うには、firestoreのクライアントを呼び出して使うだけで簡単。
参考
Firebase: Developing an App Engine service with Python and Cloud Firestore