Snowflake CLIを利用したStreamlit in Snowflakeアプリの開発、GitHub Actionsを用いたCICD
はじめに
Streamlit in Snowflake(以下 SiS)は、Snowflake 上で Streamlit アプリを実行するための機能です。インフラ管理などなく、気軽に Streamlit アプリを Snowflake 上で実行できるため、非常に便利な機能です。
ただ、現在では Git 統合、CI/CD のサポートが不十分[1]で、アプリのデプロイが煩雑でした。実際私はSnowpark APIを利用して、stage に upload する Python コードをカスタムで書いてました。
一方、Snowflake CLI が Public Preview になり、CLI で Snowflake 上で実行されるアプリを作成、管理、更新、表示できるようになりました。
この Snowflake CLI を利用することで、SiS アプリを簡単にデプロイできるようになりました。
こちらの記事では、Snowflake CLI を利用して SiS アプリを開発、また、GitHub Actions を用いてデプロイする方法を紹介します。
ディレクトリ構成
.
├── README.md
├── Makefile
├── pyproject.toml
├── poetry.lock
├── apps
│ ├── example_streamlit
│ │ ├── .snowflake
│ │ │ ├── config_ci.json
│ │ │ └── config.json
│ │ ├── common
│ │ │ └── hello.py
│ │ ├── environment.yml
│ │ ├── snowflake.yml
│ │ └── streamlit_app.py
│ └── app2
└── .github
└── workflows
├── CI.yml
├── CD_example_streamlit.yml
└── CD_workflow_base.yml
このリポジトリでは、apps
ディレクトリに SiS アプリを格納しています。example_streamlit
ディレクトリには、SiS アプリの設定ファイルや Streamlit アプリのコードが格納されています。app2
ディレクトリには、別の SiS アプリが格納されています。
サンプルの Streamlit のアプリコードは以下の通りです。
import streamlit as st
from common.hello import say_hello
st.title(f"Example streamlit app. {say_hello()}")
def say_hello():
return "Hello, World!"
SiSアプリの設定ファイル
SiS アプリの設定ファイルは、snowflake.yml
と environment.yml
の 2 つです。snowflake.yml
は、SiS アプリの設定を記述するファイルで、environment.yml
は、SiS アプリの実行に必要なライブラリを記述するファイルです。
definition_version: 1
streamlit:
name: example_streamlit
stage: STAGE_NAME
query_warehouse: WAREHOUSE_NAME
main_file: streamlit_app.py
env_file: environment.yml
additional_source_files:
- common/hello.py
# 今回はシングルページアプリなので、以下の設定は不要
# pages_dir: pages/
name: sf_env
channels:
- snowflake
dependencies:
- pandas # ここに必要なライブラリを記述
Snowflake認証情報の設定
Snowflake CLI を利用するためには、Snowflake 認証情報を設定する必要があります。認証情報は、config.toml
と config_ci.toml
の 2 つのファイルに記述します。
default_connection_name = "snowflake"
[connections]
[connections.snowflake]
account = "ACCOUNT_NAME"
user = "USER_NAME"
role = "ROLE_NAME"
database = "DATABASE_NAME"
schema = "SCHEMA_NAME"
warehouse = "WAREHOUSE_NAME"
authenticator = "SNOWFLAKE_JWT"
private_key_path = "path/to/private_key"
以下は CI/CD 用の設定ファイルの例です。
default_connection_name = "snowflake"
[connections]
[connections.snowflake]
account = "ACCOUNT_NAME"
role = "ROLE_NAME"
database = "DATABASE_NAME"
schema = "SCHEMA_NAME"
warehouse = "WAREHOUSE_NAME"
local Python環境の設定
local で SiS アプリを実行するために、Python 環境を設定します。ここでは、Poetryを利用して Python 環境を構築します。
poetry add snowflake-connector-python==${SNOWFLAKE_CONNECTOR_PYTHON} streamlit==${STREAMLIT_VERSION}
poetry add --group dev black isort flake8 mypy snowflake-cli-labs
ついでに、Makefile
の設定をします。
init:
poetry install
poetry run pre-commit install
new_streamlit_app: __require_streamlit_app_name__
cp -r apps/example_streamlit apps/${STREAMLIT_APP_NAME}
cd apps/${STREAMLIT_APP_NAME}
format:
poetry run isort apps/
poetry run black apps/
lint:
poetry run flake8 apps/
poetry run black --check apps/
poetry run isort --check-only apps/
poetry run mypy apps/
run_streamlit: __require_streamlit_app_name__
cd apps/${STREAMLIT_APP_NAME} && \
poetry run streamlit run streamlit_app.py
deploy_streamlit: __require_streamlit_app_name__
cd apps/${STREAMLIT_APP_NAME} && \
poetry run snow --config-file .snowflake/config.toml \
streamlit deploy --replace
deploy_streamlit_ci: __require_streamlit_app_name__
cd apps/${STREAMLIT_APP_NAME} && \
poetry run snow --config-file .snowflake/config_ci.toml \
streamlit deploy --replace
__require_streamlit_app_name__:
@[ -n "$(STREAMLIT_APP_NAME)" ] || (echo "[ERROR] Parameter [STREAMLIT_APP_NAME] is requierd" 1>&2 && echo "(e.g) make xxx STREAMLIT_APP_NAME=hoge" 1>&2 && exit 1)
これで
-
make init
で Python 環境を構築 -
make new_streamlit_app STREAMLIT_APP_NAME=example_streamlit
で新しい SiS アプリを作成 -
make format
でコードフォーマット -
make lint
でコードの Lint -
make run_streamlit STREAMLIT_APP_NAME=example_streamlit
でローカルで SiS アプリを実行 -
make deploy_streamlit STREAMLIT_APP_NAME=example_streamlit
で SiS アプリをデプロイ
ができるようになります。
GitHub Actionsを利用したCI/CD
GitHub Actions を利用して、SiS アプリの CI/CD を行います。
以下は、CI の設定ファイルです。こちらで GitHub 上で PR が作成されたときに、かつ、apps
ディレクトリ以下のファイルが変更された場合に、Lint を行います。
name: CI
on:
pull_request:
types: [opened, synchronize]
paths:
- "apps/**"
branches:
- master
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Set up Python
# This is the version of the action for setting up Python, not the Python version.
uses: actions/setup-python@v5
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.11'
- name: Install poetry
run: |
curl -sSL https://install.python-poetry.org | python - --version 1.8.2
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
- name: Poetry Version
run: |
poetry --version
- name: Poetry Install Dependencies
run: |
poetry install
- name: lint
run: make lint
以下は、SiS アプリをデプロイするための GitHub Actions の設定ファイルです。
name: Streamlit in Snowflake deploy base
on:
workflow_call:
inputs:
streamlit_app_name:
required: true
type: string
secrets:
SNOWFLAKE_USER:
required: true
description: "Snowflake user name"
SNOWFLAKE_PASSWORD:
required: true
description: "Snowflake password"
jobs:
streamlit_deploy:
name: SiS Deploy
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
pull-requests: write
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Set up Python
# This is the version of the action for setting up Python, not the Python version.
uses: actions/setup-python@v5
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.11'
- name: Install poetry
run: |
curl -sSL https://install.python-poetry.org | python - --version 1.8.2
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
- name: Poetry Version
run: |
poetry --version
- name: Poetry Install Dependencies
run: |
poetry install
- name: lint
run: make lint
- name: deploy Sis App
env:
SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }}
SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }}
run: |
make deploy_streamlit_ci STREAMLIT_APP_NAME=${{ inputs.streamlit_app_name }}
以下は、example_streamlit
アプリをデプロイするための設定ファイルです。
name: Deploy example_streamlit app
on:
push:
branches:
- master
paths:
- 'apps/example_streamlit/**'
jobs:
call_CD_workflow:
uses: ./.github/workflows/CD_workflow_base.yml
permissions:
id-token: write
contents: read
pull-requests: write
with:
streamlit_app_name: example_streamlit
secrets:
SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }}
SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PASSWORD }}
これで、PR がマージされたときに、example_streamlit
アプリがデプロイされるようになります🎉
おわりに
Snowflake CLI を利用することで、SiS アプリの開発、デプロイが簡単になりました。また、GitHub Actions を利用することで、CI/CD も簡単に設定できるようになりました。SiS アプリをチームで開発していく、そして設定を安全に管理していくのに便利なのでぜひお試しください!
Discussion