[streamlit] 다중 페이지 앱에서 위젯으로 작업하기

[출처] https://docs.streamlit.io/develop/concepts/multipage-apps/widgets

 

Streamlit Docs

Join the community Streamlit is more than just a way to make data apps, it's also a community of creators that share their apps and ideas and help each other make their work better. Please come join us on the community forum. We love to hear your questions

docs.streamlit.io


스트림릿 앱에서 위젯을 생성하면 스트림릿은 위젯 ID를 생성하고 이를 사용하여 위젯을 상태 저장소로 만듭니다. 사용자 상호 작용으로 앱이 재실행되면 Streamlit은 위젯의 값을 ID에 연결하여 위젯의 값을 추적합니다. 특히 위젯의 ID는 위젯이 생성된 페이지에 따라 달라집니다. 서로 다른 두 페이지에 동일한 위젯을 정의한 경우 페이지를 전환하면 위젯이 기본값으로 재설정됩니다.

이 가이드에서는 위젯이 모든 페이지에서 상태 저장 상태를 유지하도록 하려는 경우 이 동작을 처리하는 세 가지 전략을 설명합니다. 위젯이 모든 페이지에 표시되는 것은 원하지 않지만 해당 페이지에서 다른 페이지로 이동했다가 다시 돌아올 때 위젯이 상태를 유지하도록 하려면 옵션 2와 3을 사용할 수 있습니다. 이러한 전략에 대한 자세한 내용은 위젯 동작 이해를 참조하세요.


1. [옵션 1](기본값): 엔트리포인트 파일에서 위젯 명령을 실행합니다.

st.Page 및 st.navigation으로 멀티페이지 앱을 정의하면 엔트리포인트 파일이 페이지 주변의 공통 요소의 프레임이 됩니다. 엔트리포인트 파일에서 위젯 명령을 실행하면 스트림릿은 위젯을 특정 페이지가 아닌 엔트리포인트 파일에 연결합니다. 엔트리포인트 파일은 앱이 재실행될 때마다 실행되므로 사용자가 페이지를 전환할 때마다 엔트리포인트 파일의 위젯은 상태 저장된 상태로 유지됩니다.

pages/ 디렉토리로 앱을 정의하는 경우에는 이 방법이 작동하지 않습니다.

다음 예시에는 모든 페이지에서 렌더링되고 상태 저장되는 사이드바의 선택 상자와 슬라이더가 포함되어 있습니다. 위젯에는 각각 할당된 키가 있으므로 페이지 내의 세션 상태를 통해 해당 값에 액세스할 수 있습니다.

Directory structure:

your-repository/
├── page_1.py
├── page_2.py
└── streamlit_app.py

streamlit_app.py:

import streamlit as st

pg = st.navigation([st.Page("page_1.py"), st.Page("page_2.py")])

st.sidebar.selectbox("Group", ["A","B","C"], key="group")
st.sidebar.slider("Size", 1, 5, key="size")

pg.run()

2. [옵션 2]: 세션 상태의 더미 키에 위젯 값을 저장합니다.

위젯에서 다른 위젯으로 이동했다가 해당 값을 유지하면서 다시 돌아오거나 여러 페이지에서 동일한 위젯을 사용하려는 경우 st.session_state에 별도의 키를 사용하여 위젯과 독립적으로 값을 저장하세요. 이 예에서는 임시 키가 위젯과 함께 사용됩니다. 임시 키는 밑줄 접두사를 사용합니다. 따라서 위젯 키로 "_my_key"가 사용되지만 데이터는 페이지 간에 보존하기 위해 "my_key"에 복사됩니다.

import streamlit as st

def store_value():
    # Copy the value to the permanent key
    st.session_state["my_key"] = st.session_state["_my_key"]

# Copy the saved value to the temporary key
st.session_state["_my_key"] = st.session_state["my_key"]
st.number_input("Number of filters", key="_my_key", on_change=store_value)

여러 위젯과 함께 작동하도록 기능화하면 다음과 같이 보일 수 있습니다:

import streamlit as st

def store_value(key):
    st.session_state[key] = st.session_state["_"+key]
def load_value(key):
    st.session_state["_"+key] = st.session_state[key]

load_value("my_key")
st.number_input("Number of filters", key="_my_key", on_change=store_value, args=["my_key"])

3. [옵션 3]: 위젯 정리 프로세스 중단하기

앱 실행이 종료되면 스트림릿은 렌더링되지 않은 모든 위젯의 데이터를 삭제합니다. 여기에는 현재 페이지에 연결되지 않은 모든 위젯의 데이터가 포함됩니다. 그러나 앱 실행 중에 키-값 쌍을 다시 저장하면 해당 키로 위젯 명령을 다시 실행할 때까지 스트림릿은 키-값 쌍을 위젯에 연결하지 않습니다.

결과적으로 모든 페이지 상단에 다음 코드가 있으면 "my_key" 키가 있는 위젯은 렌더링 여부에 관계없이 해당 값을 유지합니다. 또는 st.navigation 및 st.Page를 사용하는 경우 페이지를 실행하기 전에 엔트리포인트 파일에 이 코드를 한 번 포함할 수 있습니다.

if "my_key" in st.session_state:
    st.session_state.my_key = st.session_state.my_key