やること
Snowflake CLIをセットアップしてStreamlitアプリをSnowflake上にデプロイします。
準備
まずはSnowflake CLIをインストールします。
インストーラーの使用が推奨されていますが、私は環境の都合でpipを使用しました。
インストールが完了したら接続情報を更新します。
以下のようなtomlファイルを作成します。
私はVScodeのSnowflake拡張機能を使用しており、そちらのtomlファイルを流用しました。
↓こちらにありました。
"C:/Users/hogehoge/.snowflake/connections.toml"
# connections.toml
[MY_CONNECTION]
account = "XXXXXXX.japan-east.azure"
user = "MY_USER"
authenticator = "snowflake"
password = "xxxxxxxxxx"
database = "MY_DATABASE"
schema = "MY_SCHEMA"
warehouse = "WH_XSMALL"
role = "MY_ROLE"
# 複数の接続情報を保持できる
[ANOTHER_ACCOUNT]
account = "yyyyy"
user = "yyyyy"
authenticator = "snowflake"
password = "yyyyy"
コマンドプロンプトを立ち上げ、tomlファイルが格納してあるディレクトリまで移動します。
以下のコマンドを実行するとSnowflake CLIで使用する接続情報をデフォルト値として設定できます。これにより、コマンド実行の度に接続情報の引数を与える必要がなくなります。
snow connection set-default MY_CONNECTION
これで準備は完了です。
やってみた
テンプレートを作成する
今回はデスクトップ配下にstreamlit_appというフォルダを作成し、そこにテンプレートを格納します。ターミナルでデスクトップまで移動し、以下のコマンドを入力します。
snow init new_streamlit_project --template example_streamlit
new_streamlit_projectはこれから作成するstreamlitアプリのプロジェクト名です。お好きなものを入力してください。
--template
はテンプレートのソースです。今回は省略していますが、--template-source
と一緒に指定することで、ローカルフォルダや自作のリポジトリからテンプレートをインポートすることができます。デフォルトでは以下のリポジトリからテンプレートをインポートします。
コマンドを実行すると立て続けに、streamlitアプリを保管するステージとアプリの実行に使うウェアハウス名、作成するstreamlitアプリ名を聞かれます。適当に入力してください。
コマンド実行が完了すると以下のようなフォルダが作られました。
- common
モジュールとして利用するpyファイルの置き場。 - paged
複数ページのアプリを作る場合はこのフォルダにpyファイルを置きます。 - environment.yml
アプリで使用するpythonモジュールのリスト。
condaのsnowflakeチャンネルからインポートするもののリストです。 - snowflake.yml
アプリの環境設定ファイル。 - streamlit_app.py
アプリのエントリポイント用pyファイル。
環境を設定する
snowflake.ymlを編集します。
データベースとスキーマを設定して以下のようになりました。
# snoflake.yml
definition_version: '2'
entities:
my_st_app:
type: streamlit
identifier:
name: my_st_app
+ schema: MY_SCHEMA
+ database: MY_DATABASE
main_file: streamlit_app.py
pages_dir: pages
query_warehouse: WH_XSMALL
stage: STREAMLIT_DEV
artifacts:
- streamlit_app.py
- environment.yml
- pages
- common/hello.py
my_st_app
はsnow init
時に設定したアプリ名です。identifier
のname
にも同じものが入っています。
テンプレートに入っていないフォルダやファイルを追加したい場合は、artifacts
に追記します。
ちなみに、このsnowflake.ymlには複数のstreamlitアプリを記載することができるようです。
デプロイする
デプロイには以下コマンドを利用します。
snow streamlit deploy --replace -p new_streamlit_project --dbname MY_DATABASE --schema MY_SCHEMA
-p
はプロジェクト名、--dbname
はデータベース名、--schema
はスキーマ名を渡します。冒頭で設定した接続情報にデータベース名やスキーマ名を含めている場合は省略できます。
--replace
を指定するとアプリが既に存在する場合に上書きすることができます。
デフォルトはfalseですが、CI/CDで利用する場合は書いておくと良いと思います。
Creating MY_DATABASE.MY_SCHEMA.STREAMLIT_DEV stage
Deploying files to @MY_DATABASE.MY_SCHEMA.STREAMLIT_DEV/my_st_app
Creating MY_DATABASE.MY_SCHEMA.my_st_app Streamlit
Streamlit successfully deployed and available under https://~
こんなログが出て完了しました。
アプリへのURLも出力されます。
コードに修正を加えて再デプロイする
ソースコードに変更を加えてもう一度デプロイしてみます。
pages配下に2つ目のページを作成しました。
# pages/second_page.py
import streamlit as st
options = ["orange", "banana", "apple"]
selected_option = st.sidebar.radio("Please select:", options)
st.title("Hello world")
先程と同じコマンドを実行します。
デプロイできました。ちゃんと新規追加したページが表示されています!
細かいことを検証する
ステージの他ファイルに影響はあるのか?
デプロイコマンドを実行するとCreating MY_DATABASE.MY_SCHEMA.STREAMLIT_DEV stage
というログが毎回出ます。実行の度にCREATE OR REPLACE
が走っていたら、他のファイルが消えてしまうかも?と思い、試してみました。
streamlitアプリをデプロイしているステージにmemo.md
を追加しました。
この状態で再度デプロイしてみます。
無事でした。
おそらく、デプロイ時にはCREATE STAGE IF NOT EXIST
として処理されているものと考えられます。
(追記)
ステージに同名のファイルがある場合は上書きとなりますが、ファイル名を変更した場合は古い方のファイルは残り続けます。
これはプロジェクト内のファイルについても同様です。
importを利用する
condaからインポートするモジュールはenvironment.yml
に書きますが、外部ステージなどに置いた自作のモジュールを記載することはできません。自作モジュールをstreamlitアプリで使用する場合はsnowflake.yml
に記載する必要があります。
# snowflake.yml
definition_version: '2'
entities:
my_st_app:
type: streamlit
identifier:
name: my_st_app
schema: MY_SCHEMA
database: MY_DATABASE
main_file: streamlit_app.py
pages_dir: pages
query_warehouse: WH_XSMALL
stage: STREAMLIT_DEV
+ imports:
+ - "@MY_STAGE/my_module.py"
artifacts:
- streamlit_app.py
- environment.yml
- pages
- common/hello.py
# streamlit_app.py
import streamlit as st
from common.hello import say_hello
+ from my_module import hello_world
st.title(f"Example streamlit app. {say_hello()}")
+ st.write(hello_world())
# my_module.py
def hello_world ():
return 'Hello World'
my_module.pyはMY_STAGEというステージに配置しています。
再度デプロイしたところ、モジュールの読み込みができていることを確認できました。
プロジェクト外のコードを流用したい場合に使えそうです。
権限を付与する
デプロイしたアプリを閲覧する権限は別のコマンドで実行する必要があります。
今回はPUBLICロールに閲覧権限を付与したいと思います。
snow streamlit share my_st_app PUBLIC
View Onlyの権限が付与されていることを確認できました!
感想
Streamlit in SnowflakeをCI/CDしていくにあたって、様々な手法がありますが、Snowflake CLIはコマンドがシンプルなので利用しやすそうだなと思いました。
Gitと連携したデプロイについても今後考えていきたいところです。