33
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Microsoft Azure TechAdvent Calendar 2022

Day 19

Streamlit を Azure App Serviceで動かす!

Last updated at Posted at 2022-12-19

はじめに

データサイエンティストな皆さんに人気が出始めている Streamlit という Webフレームワークがあります。

とても簡易的に作れて便利なフレームワークですが、これを Azure App Service で動かす手順をあまり見かけないので書き記しておきます。
ここで解説する手順ですが、先にやり方をまとめておくと次のようになります。

  1. ローカルで開発(VSCode の devContainerを使う)
  2. Azure App Serviceを作成
    • Python 3.10で作る
    • SCMデプロイ時にビルドが走るようにアプリケーション設定に値をセット
    • Startupコマンドに streamlit 用のコマンドをセット
  3. GitHub にRepositoryを作成し、ソースコードをPush
  4. Azure App ServiceからGitHub 連携をセットアップ
  5. デプロイ結果を確認

GitHub+App Service に慣れている人からすれば、ほぼいつも通りのCI/CDですが、2の設定がポイントです。そこだけ知りたい、という方はそこだけご確認ください。

1. ローカルで Streamlit を動かす

仮想環境を作り、そこに Streamlit をインストールする手順が推奨だそうですが、Visual Studio Code の devContainer で環境を作る方が好みなので今回はそっちでやります。

  • ローカル環境
    • Visual Studio Code
      • devContainerプラグイン
    • Docker Desktop

devContainer で Python 環境を作る

適当なフォルダを作り、そこに Dockerfile を次のように作成します。

FROM python:3.10-bullseye

RUN pip install streamlit numpy pandas matplotlib

2022/12/19の時点で Streamlit は Python 3.10までがバージョンの上限、と公式に記載があるので最新である 3.11ではなく3.10を指定しています。 pip でインストールするのは Streamlit だけでいいのですが、どうせデータ分析するならnumpy,pandas, matplotlibとか使うよね〜と思って追記しています。不要なら削除、他に必要なものがあるなら後ろに追加しましょう。

フォルダをコンテナとして開く

Visual Studio Code 立ち上げて、左下の緑アイコンをクリックします。このアイコンは devContainerプラグインが VSCode にインストールされていないと表示されません。表示されていない人はインストールしましょう。

Open Folder in Containerを選択します。フォルダ選択ダイアログが立ち上がるので Dockerfile が存在するフォルダを指定します。

image.png

From 'Dockerfile" を選びます。

image.png

コンテナに追加する アプリを選びます。後で GitHub へプッシュするので git を入れておきましょう。
image.png

すると .devContainerフォルダが新規作成され、その中にdevContainer.jsonという設定ファイルも新規作成されます。そして、Dockerfileを使ってコンテナが立ち上がり、そのコンテナにVSCodeから接続している状態になります。接続した状態は、このように左下の緑アイコンが変化します。
image.png

もし立ち上げに失敗した場合は、フォルダをVSCodeで開き直してください。するとフォルダをコンテナで開き直しますか?と聞かれるのでOKを選択すれば再度接続してくれるはずです。

では、稼働確認です。ターミナルをVSCodeで立ち上げて次のコマンドを叩きます。

streamlit hello

ポートフォワードについてのこんなダイアログが上がってくるので、ブラウザーで開くを選択します。

image.png

ブラウザーでこんなデモ画面が表示されれば、ローカルの環境構築はOKです。
image.png

実装する

適当にテスト用のページを実装しましょう。フォルダ内に main.py というファイルを新規作成して次のように実装します。
image.png

import streamlit as st

st.title('Hello!')

先ほど streamlit hello を入力したターミナルを CTRL+Cで停止して、次のコマンドを入力します。

streamlit run main.py

先ほどのデモ画面が表示されているブラウザをリロードすると、こんな感じになるはずです。
image.png

App Service デプロイ後に pip でインストールしたいパッケージを requirements.txtに書く

Dockerfile に記載した環境に必要なパッケージは、このままでは App Service には存在しないのでうまく動きません。 App Serviceは立ち上げ時に requirements.txt に記載されたパッケージを pip でインストールしてくれる機能があります。なので、requirements.txtファイルを新規作成して、そこにDockerfileに記載したパッケージを記載します。

image.png

requirements.txt
streamlit
numpy
pandas
matplotlib

2. Azure App Serviceを作成

次の情報をベースに Azureで App Serviceを作成してください。他の値はご自由に。

  • 公開: コード
  • ランタイム スタック: Python 3.10

Streamlit 用に App Service を構成する

この後、GitHubからソースをデプロイさせるのですが、デプロイされた App Service側では  requirements.txtを読んで pip でパッケージをインストールするセットアップをしてもらう必要があります。この動作は構成で行います。アプケーション設定にSCM_DO_BUILD_DURING_DEPLOYMENTというKEYを作り、値にtrueまたは1をセットします。最後に保存ボタンをクリックすることをお忘れなく。

image.png

次にスタートアップスクリプトを設定します。streamlit はWebサーバー機能を含んでいますので、streamlit をスタートアップで動かさなければなりません。ローカルで実装したのはmain.pyでしたのでコマンドは次のようになります。

python -m streamlit run main.py   --server.port 8000 --server.address 0.0.0.0

これを、全般設定のスタートアップ コマンドに設定します。くどいようですが最後に保存ボタンをクリックすることをお忘れなく。
image.png

3. GitHub にRepositoryを作成し、ソースコードをPush

特に説明は不要でしょう。この操作は純粋なGitの操作になります。作成ずみのローカル環境をGitHubなどのRemoteリポジトリに紐づけるのは一般的に次のようなコマンドを叩きます。

git init
git remote add origin Path_To_Remote_Repository
git commit --allow-empty -m "first commit"
git push -u origin main

Path_To_Remote_Repositoryは、GitHubで作成したリポジトリのPathに置き換えてください。最初に空のコミットをPushするコマンドになっているのは単に私の趣味です。

4. Azure App ServiceからGitHub 連携をセットアップ

メニューのデプロイセンターでソースを GitHub とし、必要ならログインしてリポジトリ、ブランチを選択します。自分でGitHubに作ったリポジトリなので特に不明点はないはずです。
image.png

保存ボタンをクリックして少し経つと、設定が終わります。GitHub に作成したレポジトリを開き、Actionを見てみましょう。パイプラインが稼働中となっています。

image.png

しばらく待つと、このパイプラインが終了します。

image.png

5. デプロイ結果を確認

App Service の概要にあるURLを開いて、デプロイ結果を確認しましょう。

image.png

無事にデプロイされました。

まとめ

Streamlit の App Serviceへのデプロイはコンテナを使った方法は見かけますが、このように直接デプロイすることもできます。(裏では結局コンテナ使っているんですけど) シンプルなのでオススメです。

AppServiceでホストしたんだから、AzureADによる認証をつけたい!という方がいらっしゃると思います。すごく簡単にできます。AzurePortalで次の操作をします。

  1. 認証クリック
  2. IDプロバイダーを追加をクリック
  3. Microsoft を選択
  4. 追加

これだけでAzureAD認証が追加されます。アクセスしたユーザーが誰なのかを知りたい、など Claimにアクセスする場合は Request Header から値を取得することができます。 streamlit を使って Request Header にアクセスするサンプルソースを作りましたので参考にしてください。(Streamlit 1.16で動作確認済み)

import streamlit as st
from streamlit.web.server.websocket_headers import _get_websocket_headers


st.title('Hello! This streamlit app is on Azure AppService.')

headers = _get_websocket_headers()
principal_name = headers.get("X-Ms-Client-Principal-Name")
principal_id = headers.get("X-Ms-Client-Principal-Id")
access_token = headers.get("X-Ms-Token-Aad-Access-Token")

st.header("AzureAD's auth results")

if principal_name is not None:
    st.markdown('X-Ms-Client-Principal-Name: ' + principal_name)
if principal_id is not None:
    st.markdown('X-Ms-Client-Principal-Id: ' + principal_id)
if access_token is not None:
    st.markdown('X-Ms-Token-Aad-Access-Token: ' + access_token)

st.header('http headers count')
st.text(len(headers))

st.header('List http headers')
if headers is not None:
    for key, value in headers.items():
        text = 'key={}, value={}'
        st.text(text.format(key, value))
33
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?