StreamlitでWebアプリを開発した場合、同社の提供するクラウド型公開サービス”Streamlit Community Cloud”を利用することで、非常に簡単にアプリをデプロイすることが可能です。 スムーズにいけば、初めての場合でも準備も含めて10分程度で公開させることができます。
目次:
- Streamlit Community Cloudへの登録(早めに)
- 利用するライブラリのリストを用意する(requirements.txtなど)
- パッケージマネージャーごとに異なる方法で、ライブラリの依存関係を明記する
- requirements.txtの書き方
- 環境変数やデータベース接続情報などをSecretsで登録
- Streamlit Cloud上で用いる場合はSecretsの設定項目内で設定
- ローカルでSecrets情報を用いたい場合には、secrets.tomlを作成する
- ユーザーIDやパスワードを設定する
- 公開させるGitHubのブランチを選択してStreamlit Community Cloudで公開
- デプロイ時、パッケージの依存関係でつまづく場合
- Streamlit Cloudとローカル環境のPythonバージョンを合わせる
- コンソールのエラーメッセージを参照しつつ、requirements.txtを修正
- パッケージ依存関係のエラーが解消できない場合、Dockerコンテナ化して他プラットフォーム上で公開するのも手
- 公開したWebアプリへのアクセスが少ない場合、一定期間で自動的にアプリがスリープ状態になる
Streamlit Community Cloudへの登録(早めに)
まず、まだStreamlit Community Cloudへ登録していない場合は登録申請をしましょう。利用可能となるまで、申請してから2営業日ほどかかる場合があります。早めに登録申請しておきましょう。
利用するライブラリのリストを用意する(requirements.txtなど)
パッケージマネージャーごとに異なる方法で、ライブラリの依存関係を明記する
requirements.txt : 公開するアプリケーションで利用している外部ライブラリを記載するもの。パッケージマネージャーがpipである場合。
condaの場合にはenvironment.yml、pipenvの場合にはPipfileなど、パッケージマネージャーごとに用意する書式が異なります。
requirements.txtの書き方
Requirements Files | User Guide - pip documentation v23.1.2
requirements.txtに記載がないと、Streamlitが外部ライブラリをうまく把握できず、デプロイの際に不具合が生じることがあります。
開発環境にインストールされたライブラリをすべてそのままデプロイ時にも利用する場合には、下記コマンドでrequirements.txtへ出力すれば良いでしょう。
$ pip3 freeze > requirements.txt
他にも公開環境で使わないライブラリをインストールしている場合には、下記コマンドで出力されたライブラリとバージョンを見ながら、手動でrequirements.txtを作成していきます。
$ pip3 freeze
requirements.txtには、外部ライブラリ「のみ」をrequirements.txtに記載します。
Streamlit自体も外部ライブラリとなるので、記載が必要となります。
Numpy, Pandas等を利用する場合も記載が必要
記載しなくて良いライブラリとして、たとえば、timeライブラリはもともとPythonに入っている標準ライブラリなのでrequirements.txtには記載不要です。
requirements.txtの作成の際、バージョンを指定して併記するのがベター。
requirements.txtへの記載例。
streamlit==0.87.0
バージョンを記載しない場合には、最新版が公開アプリにインストールされます。
streamlit
環境変数やデータベース接続情報などをSecretsで登録
Streamlit Cloud上で用いる場合はSecretsの設定項目内で設定
APIキーなどの環境変数やデータベース接続情報をStreamlit Cloudで用いたい場合、”Secrets”と呼ばれるStreamlit Cloud設定項目内で変数として格納してあげる必要があります。
Secrets management - Streamlit Docs
機密情報をハードコーディングして公開するのは、セキュリティリスクが大きいため絶対に避けましょう。Secrets項目で格納し、アプリ内で呼び出すようにします。
# Everything in this section will be available as an environment variable
db_username = "Jane"
db_password = "12345qwerty"
# You can also add other sections if you like.
# The contents of sections as shown below will not become environment variables,
# but they'll be easily accessible from within Streamlit anyway as we show
# later in this doc.
[my_cool_secrets]
things_i_like = ["Streamlit", "Python"]
Secrets management - Streamlit Docs
Secretsにおいては、TOML形式と呼ばれる形式で入力する必要があります。
あまり気にせず、通常どおり変数を格納するつもりで書いていけば良いでしょう。
Secretsへ保存した変数は、st.secrets[’key’]のように辞書形式で呼び出すことができるほか、os.environ[’key’]としてOS環境変数のように扱って呼び出すことが可能です。
os.environ[’key’] を利用すれば、ローカル環境と公開環境でSecretsを呼び出す際にもコードを変更する必要がなくなります。
mport streamlit as st
# Everything is accessible via the st.secrets dict:
st.write("DB username:", st.secrets["db_username"])
st.write("DB password:", st.secrets["db_password"])
st.write("My cool secrets:", st.secrets["my_cool_secrets"]["things_i_like"])
# And the root-level secrets are also accessible as environment variables:
import os
st.write(
"Has environment variables been set:",
os.environ["db_username"] == st.secrets["db_username"],
)
Secrets management - Streamlit Docs
ローカルでSecrets情報を用いたい場合には、secrets.tomlを作成する
ローカル環境でSecrets情報を用いたい場合には、別途secrets.tomlをファイルとして作成する必要があります。
また、このsecrets.tomlは.streamlitフォルダの中に格納されている必要があります。
Secrets management - Streamlit Docs
上画像での警告があるとおり、ローカルでsecrets.tomlを作成する場合、誤ってGit上で追加・公開されてしまう危険性があります。予防のために .gitignoreファイルで除外設定をしておきましょう。
参考タグ: Git
ユーザーIDやパスワードを設定する
一般公開せずに自社や特定のグループ内でのみ利用したい場合、パスワードのみの設定(グローバルパスワード)またはユーザーIDを用意し、ユーザーごとにパスワードを設定するなどを行い、権限管理を行います。
ユーザーIDおよびパスワードについても、同様に”Secrets”設定で管理することができます。チェックについては、別途ファイル内に認証のための関数を記述する必要があります。
サンプルコード含めて手順は Authentication without SSO - Streamlit Docs に記載がありますので、こちらを参考に実装しましょう。
公開させるGitHubのブランチを選択してStreamlit Community Cloudで公開
上記までが準備できたら、Streamlitで公開させるGitHubのブランチおよびメインファイルのパスを選択するだけで公開が可能となります。
私はYouTube Data APIを用いたWebアプリのGitHubリポジトリ・ブランチをStreamlit Community Cloudで公開しました。
YouTube Data APIを用いてカスタム検索を行うアプリケーションです。一般公開ではなく特定の取引先様のみが業務で利用するものだったので、さくっとStreamlitで実装、Streamlit Community Cloudで公開しました。
デプロイ時、パッケージの依存関係でつまづく場合
requirements.txtに記載したパッケージについて、Streamlit Cloudでデプロイさせたときに依存関係で問題が生じることがあります。
その場合、以下を確認しましょう。
Streamlit Cloudとローカル環境のPythonバージョンを合わせる
開発時ローカル環境とStreramlit CloudとのPythonバージョンが合っているか確認します。
Streamlit CloudはデフォルトではPython3.8が選択されていますが、アプリをデプロイさせるときにAdvanced Settingsからバージョンの選択が可能です。
一度デプロイしてしまったアプリについてはPythonのバージョンを変更させることはできないため、その場合には一度アプリ自体をDeleteしてから再度デプロイを行うなどしましょう。
コンソールのエラーメッセージを参照しつつ、requirements.txtを修正
Steamlit Cloudでデプロイに失敗する場合、アプリ画面にて右下の”Manage App”をクリックすると、コンソールに出力された内容が確認できます。
このコンソールに、「どのパッケージのインストール時にエラーが発生したか」「解決するにはどうすれば良いか」が吐き出されるので、確認して対応するようにしましょう。
たとえば私の場合、以下2つのエラーに遭遇しました。
ERROR: Cannot install langchain==0.0.262 and langchain==0.0.281 because these package versions have conflicting dependencies.
The conflict is caused by:
The user requested langchain==0.0.262
The user requested langchain==0.0.281
To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict
上記はlangchainについてのエラーです。指示にあるとおり、requirements.txtにて指定バージョンの範囲を緩くするか、バージョン指定自体を削除します。
Collecting sklearn==0.0.post7
Downloading sklearn-0.0.post7.tar.gz (3.6 kB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'error'
error: subprocess-exited-with-error
× python setup.py egg_info did not run successfully.
│ exit code: 1
╰─> [18 lines of output]
The 'sklearn' PyPI package is deprecated, use 'scikit-learn'
rather than 'sklearn' for pip commands.
Here is how to fix this error in the main use cases:
- use 'pip install scikit-learn' rather than 'pip install sklearn'
- replace 'sklearn' by 'scikit-learn' in your pip requirements files
(requirements.txt, setup.py, setup.cfg, Pipfile, etc ...)
- if the 'sklearn' package is used by one of your dependencies,
it would be great if you take some time to track which package uses
'sklearn' instead of 'scikit-learn' and report it to their issue tracker
- as a last resort, set the environment variable
上記はscikit learnライブラリについてのエラー。どうやら現在ではインストール時の名称が変更となり、sklearnではなくschikit-learnとの名称でインストールするように、とあります。
指示にしたがって、ローカル環境でインストールし直した後、ふたたびrequirements.txtを更新します。
$ pip3 uninstall sklearn
$ pip3 install schikit-learn
$ rm requirements.txt
$ pip3 freeze > requirements.txt
$ git add requirements.txt
$ git commit -m "Update requirements.txt"
$ git push origin main
GitHub上で更新したら、Streamlit CloudにおけるアプリをRebootさせて変更を反映させます。
パッケージ依存関係のエラーが解消できない場合、Dockerコンテナ化して他プラットフォーム上で公開するのも手
上記諸々を試しても、うまくパッケージ依存関係のエラーが解消できない場合には、ローカル環境をDockerコンテナ化して他サービスでデプロイするのも一つの手です。
Streamlit CloudはDockerによるデプロイ・ホスティングには対応していませんが、他プラットフォーム上でDockerによってStreamlit製アプリをデプロイすることは可能です。
公開したWebアプリへのアクセスが少ない場合、一定期間で自動的にアプリがスリープ状態になる
公開したWebアプリへのアクセスが少ない場合、一定期間で自動的にアプリがスリープ状態になってしまうので注意してください。
スリープ状態となったWebアプリは、メールで通知がくるほか、ログイン後のダッシュボード画面で下記のようにスリープマークが表示されます。
ダッシュボードからアプリにアクセスし、Awakenボタンを押して再度ビルド処理を行うことで、再度公開状態に戻すことが可能です。
以前は管理画面・ダッシュボードからしか再起動させることができませんでしたが、現在では公開先にも”Awaken”ボタンが表示されるようになりました。開発者自身でなくても、公開先からアプリをスリープ状態から復帰させることが可能です。
アクセス状態に関わらず常にWebアプリを公開状態・スリープなしの状態とさせたい場合には、有料プランへの加入が必要となるようです。
It's not possible to keep Streamlit apps awake at all times if they're hosted on Streamlit Community Cloud. If you need the app to be awake at all times regardless of traffic, I'd recommend looking into paid hosting options.
Streamlit app going to sleep due to less traffic - Stack Overflow
この記事の気になった箇所を読み返す:
- Streamlit Community Cloudへの登録(早めに)
- 利用するライブラリのリストを用意する(requirements.txtなど)
- パッケージマネージャーごとに異なる方法で、ライブラリの依存関係を明記する
- requirements.txtの書き方
- 環境変数やデータベース接続情報などをSecretsで登録
- Streamlit Cloud上で用いる場合はSecretsの設定項目内で設定
- ローカルでSecrets情報を用いたい場合には、secrets.tomlを作成する
- ユーザーIDやパスワードを設定する
- 公開させるGitHubのブランチを選択してStreamlit Community Cloudで公開
- デプロイ時、パッケージの依存関係でつまづく場合
- Streamlit Cloudとローカル環境のPythonバージョンを合わせる
- コンソールのエラーメッセージを参照しつつ、requirements.txtを修正
- パッケージ依存関係のエラーが解消できない場合、Dockerコンテナ化して他プラットフォーム上で公開するのも手
- 公開したWebアプリへのアクセスが少ない場合、一定期間で自動的にアプリがスリープ状態になる
Category: 開発・プログラミング | エンジニアリング