🛝

Streamlit 1.34.0からdialogが使えるようになった話

2024/05/08に公開

TL;DR

  • Streamlitの1.34.0で、st.experimental_dialogが実装された

st.experimental_dialog

Streamlit1.34.0にて、st.experimental_dialogがローンチされました(リリースノート)。個人的には大きいニュースなのでご存知の方も多いとは思いつつ、具体的には

といったように、ダイアログを表示する機能です。用途としては、ユーザに入力させた内容を繰り返し表示させたい時や、エラー処理に使いたい時に使うイメージですね。
もちろんカスタムコンポーネントが実装できるので、自前で用意する選択肢もあります。ですがStreamlitを使うなら、なるべく純正の機能を使ったアプリを提供していきたいなと思っていたので、嬉しいアップデートです。

先ほどの例を実装したのが下記のコードになります(GitHubリポジトリ)。
ポイントとしては、st.buttonのように関数として呼び出すのではなく、自分で実装した関数のデコレータとして扱う点です。これによって、画面全体を再実行する際にも影響がなく、スマートなダイアログを見せることができます。

@st.experimental_dialog("承認確認")
def approve_button3():
    st.write("本当に良い?")
    if st.button("OKですって"):
        st.session_state["ok_button3"] = True
        st.rerun()
if "ok_button3" not in st.session_state:
    if st.button("承認"):
        approve_button3()
if st.session_state.get("ok_button3", False):
    st.success("承認されました3")

従来の機能との比較

例えば、ユーザに承認のボタンを押させて、念の為もう一回確認してほしい機能を作りたいとします(ちょっとJTCっぽいですが・・・実装規模が小さく済む・・・)。
今までの機能でどうできるか考えてみると、

  • st.buttonのみで対応

    button1 = st.button("シンプルなボタン")
    def approve_button1():
        st.session_state["ok_button1"] = True
    if button1:
        st.markdown("本当に良い?")
        st.button("OK", on_click=approve_button1, key="1")
    if st.session_state.get("ok_button1", False):
        st.success("承認されました1")
    
    • 出力例(Streamlitっぽいけど...)

  • st.popoverを使う

    def approve_button2():
        st.session_state["ok_button2"] = True
    with st.popover("ポップオーバーのボタン"):
        st.markdown("本当に良い?")
        st.button("OKだよ", on_click=approve_button2, key="2")
    if st.session_state.get("ok_button2", False):
        st.success("承認されました2")
    
    • 出力例(表示場所を調整する必要があるので大変)

といったように、再実行が走ってしまうライブラリ特有の仕様もあって、思ったような実装ができないという問題がありました。他に上手い実装方法もあるとは思いますが、純粋な機能だけで頑張ろうとすると必ず詰まると思います。

終わりに

Streamlit1.34.0のアップデートの大きな目玉はこのdialogだと思っています。つい最近のアプデなので、早いうちに試したことだけでも書き残したいという思いから記事を書いています。
他にも1.34.0のアップデートでは、特定のキャッシュが削除できたり、クエリパラメータを一括で設定できるのも地味に嬉しいポイントです。色々調べて面白いことがわかったら、記事にできると良いなと思っています。

Discussion