Streamlit with Google Cloud: Firebase 認証
前回に引き続き、今回は Streamlit アプリケーションに、Firebase 認証によるログイン機能を実装し、Cloud Run で動かしてみます。
この連載では、Google Cloud 上で Streamlit を上手に動かす方法をご紹介しています。
- Cloud Run での Hello, world!
- Firebase 認証との連携 (本記事)
- BigQuery へのクエリ
- GitHub、GitLab、Cloud Build での CI/CD
Firebase プロジェクトを準備する
1. プロジェクトを追加
https://console.firebase.google.com/ で「プロジェクトを作成」をクリック。
プロジェクトは選択肢の中からクラウドに用意したプロジェクト名を選択して、続行。
プランを確認、続行と進みます。「このプロジェクトで Google アナリティクスを有効にする」の選択肢を外しつつ「Firebase を追加」します。
「新しいプロジェクトの準備ができました」と表示されたら「続行」してください。
2. プロジェクトにウェブアプリ追加
HTML タグのアイコンをクリックして、ウェブアプリの追加を開始します。
任意の名前を指定したら「アプリを登録」し「コンソールに進む」
以下の画面になったら「Authentication」をクリックします。
「始める」をクリックして、「メール / パスワード」を選択、有効にして保存します。
「Users」タブに切りかえ、任意のユーザーを一人追加してみましょう。
3. ウェブアプリの SDK 設定値を取得
画面左上の歯車アイコンから「プロジェクトの設定」を選び、下図右側の設定がみえるところまでスクロールします。
画面の firebaseConfig
の値を参考に、以下の形式で config.py
として保存します。
firebase = {
"apiKey": "apiKey",
"authDomain": "projectId.firebaseapp.com",
"databaseURL": "https://databaseName.firebaseio.com",
"storageBucket": "projectId.appspot.com"
}
Python × Firebase 認証の実装
1. ライブラリのインストール
Pyrebase4 を導入します。
poetry add Pyrebase4
2. 認証ロジックの実装
Firebase 認証を行うロジックを firebase.py
として保存します。認証されたユーザーは st.session_state
に入れておく実装としてみましょう。
import json
import pyrebase
import requests
import streamlit as st
from config import firebase as cfg
firebase = pyrebase.initialize_app(cfg)
auth = firebase.auth()
def authenticate(email, password):
try:
user = auth.sign_in_with_email_and_password(email, password)
st.session_state.user = user
return True
except requests.exceptions.HTTPError as e:
msg = json.loads(e.args[1])["error"]["message"]
if msg == "EMAIL_NOT_FOUND" or msg == "INVALID_PASSWORD":
st.error("メールアドレスかパスワードに誤りがあります。")
elif msg == "USER_DISABLED":
st.error("このユーザーは無効化されています。管理者にお問い合わせください。")
elif msg == "TOO_MANY_ATTEMPTS_TRY_LATER":
st.error("試行回数が多すぎます。しばらく経ってからお試しください。")
else:
st.error("ログインに失敗しました。")
if "user" in st.session_state:
del st.session_state.user
return False
def refresh():
if "user" not in st.session_state:
return False
try:
user = auth.refresh(st.session_state.user["refreshToken"])
st.session_state.user = user
return True
except Exception:
del st.session_state.user
return False
3. 画面の制御を実装
- の関数を利用し、認証状態によって画面遷移する home.py に修正してみます。
import streamlit as st
import firebase
def login():
email = st.empty()
email = email.text_input("Email アドレスを入力してください")
password = st.text_input("パスワードを入力してください", type="password")
submit = st.button("ログイン")
if submit and firebase.authenticate(email, password):
st.experimental_rerun()
def index():
if not firebase.refresh():
st.experimental_rerun()
return
st.text("ログインしました")
if "user" not in st.session_state:
login()
else:
index()
静的解析をしつつ、スタイルもフォーマットします。
./test.sh
4. クラウドへのデプロイ
問題なければ、これを Cloud Run にデプロイしてみましょう!
gcloud run deploy my-app --region "asia-northeast1" --source .
Cloud Run のサービスにアクセスしてみると、以下のような画面に変わっていると思います。Firebase に登録したユーザーでログインしてみましょう。
「ログインしました」というメッセージが表示されましたか?されていれば、認証ロジック完成です 🎉🎉🎉
次は BigQuery へのクエリーとその可視化を実装してみます。
Discussion
めちゃ参考になりました!
主に読者向けに共有です。
v1.37から
st.experimental_rerun()
が使用できなくなっており、代わりにst.rerun()
を使用する必要があるみたいです。サンプルコードでは、
st.experimental_rerun()
を使用しているため、st.rerun()
に書き換えないとエラーが発生します。