Streamlit fragments 사용하기

Streamlit fragments 사용하기

Streamlit
Streamlit fragments 사용하기
Author

gabriel yang

Published

September 19, 2024


Streamlit은 데이터 과학자와 개발자들이 빠르고 쉽게 웹 애플리케이션을 만들 수 있게 해주는 강력한 Python 라이브러리입니다. Streamlit의 최신 기능 중 하나인 ’fragments’는 앱의 구조를 개선하고 성능을 최적화하는 데 중요한 역할을 합니다. 이 글에서는 st.fragment를 사용한 Streamlit fragments의 개념, 사용법, 그리고 Plotly를 활용한 간단한 예시 코드를 살펴보겠습니다.

Fragments란?

Streamlit fragments는 앱의 일부분을 독립적인 단위로 캡슐화하는 방법입니다. 이는 앱의 상태 관리, 성능 최적화, 그리고 전체적인 구조화에 중요한 역할을 합니다.

fragments의 주요 특징:

  1. 상태 격리: 각 fragment는 독립적인 상태를 가집니다.
  2. 성능 최적화: 필요한 부분만 재계산됩니다.
  3. 모듈화: 앱을 더 작고 관리하기 쉬운 부분으로 나눕니다.

st.fragment와 Plotly를 사용한 간단한 예시

다음은 Plotly를 사용하여 시계열 데이터를 시각화하는 간단한 예시입니다:

import streamlit as st
import pandas as pd
import plotly.express as px
import numpy as np
from datetime import datetime, timedelta

@st.fragment
def time_series_fragment(id):
    st.subheader(f"시계열 데이터 {id}")

    # 세션 상태에서 데이터 가져오기 또는 초기화
    if f'time_series_data_{id}' not in st.session_state:
        # 초기 데이터 생성
        dates = [datetime.now().date() - timedelta(days=x) for x in range(30)]
        values = np.cumsum(np.random.randn(30))
        st.session_state[f'time_series_data_{id}'] = pd.DataFrame({
            'Date': dates,
            'Value': values
        })

    data = st.session_state[f'time_series_data_{id}']

    # Plotly 차트 생성
    fig = px.line(data, x='Date', y='Value', title=f'시계열 데이터 {id}')

    # Streamlit에 차트 표시
    st.plotly_chart(fig, use_container_width=True)

    # 상호작용 요소
    if st.button("데이터 새로고침", key=f"refresh_{id}"):
        # 새로운 랜덤 데이터 생성
        dates = [datetime.now().date() - timedelta(days=x) for x in range(30)]
        values = np.cumsum(np.random.randn(30))
        st.session_state[f'time_series_data_{id}'] = pd.DataFrame({
            'Date': dates,
            'Value': values
        })
        st.rerun()

    # 데이터 통계 표시
    st.write(f"데이터 요약:")
    st.write(f"평균값: {data['Value'].mean():.2f}")
    st.write(f"최대값: {data['Value'].max():.2f}")
    st.write(f"최소값: {data['Value'].min():.2f}")

# 메인 앱
def main():
    st.title("시계열 데이터 대시보드")

    col1, col2 = st.columns(2)
    with col1:
        time_series_fragment("A")
    with col2:
        time_series_fragment("B")

if __name__ == "__main__":
    main()

이 예시에서 time_series_fragment@st.fragment 데코레이터를 사용하여 정의됩니다. 각 fragment는 다음과 같은 특징을 가집니다:

  1. 고유한 id를 받아 독립적인 데이터와 상태를 관리합니다.
  2. Plotly Express를 사용하여 간단한 시계열 선 그래프를 생성합니다.
  3. “데이터 새로고침” 버튼을 통해 새로운 랜덤 데이터를 생성할 수 있습니다.
  4. 데이터의 기본적인 통계 정보(평균, 최대, 최소)를 표시합니다.
  5. 각 요소(버튼 등)에 고유한 키를 사용하여 다른 fragment 인스턴스와의 충돌을 방지합니다.
  6. st.rerun()은 Streamlit 앱에서 특정 조건이나 이벤트가 발생했을 때 전체 스크립트를 다시 실행하는 함수입니다. 이 함수는 주로 앱의 상태를 갱신하거나 특정 상호작용 후에 새로고침이 필요할 때 사용됩니다. 실행되면, 마치 사용자가 새로고침 버튼을 누른 것처럼 전체 애플리케이션이 처음부터 다시 시작됩니다.
  7. use_container_width=True 옵션은 그래프가 사용자의 화면 너비에 맞춰 자동으로 크기가 조정되도록 설정합니다.

session_state를 사용하는 이유

session_state는 Streamlit의 상태를 유지하는 데 중요한 역할을 합니다. 기본적으로 Streamlit 앱은 사용자의 입력에 따라 매번 전체 스크립트를 재실행하기 때문에 상태가 사라질 수 있습니다.

특히 Fragments를 사용할 때, 버튼 클릭이나 사용자 입력과 같은 이벤트가 발생할 때마다 해당 함수만 재실행되므로 상태가 유지되지 않을 수 있습니다. 따라서 st.session_state를 사용하면, 다음과 같은 이유로 상태를 관리하고 유지할 수 있습니다:

  1. 상태 저장: 사용자가 입력한 값이나 버튼 클릭 여부와 같은 상태를 유지할 수 있습니다.
  2. 재실행 간의 연속성: 전체 스크립트 또는 Fragment가 재실행될 때도 사용자 상태를 잃지 않음으로써 더 자연스러운 상호작용이 가능해집니다.
  3. 다중 Fragment 간 데이터 공유: 여러 Fragment가 있을 때 session_state를 통해 데이터를 공유하거나 전역적으로 관리할 수 있습니다.

Fragments의 장점

  1. 성능 최적화: 각 fragment는 필요할 때만 재계산되어 앱의 전체적인 성능이 향상됩니다.
  2. 상태 관리: 각 fragment는 독립적인 상태를 가져 복잡한 앱 구조에서도 상태 관리가 용이합니다.
  3. 코드 재사용성: 동일한 fragment를 여러 번 사용할 수 있어 코드 중복을 줄일 수 있습니다.
  4. 유지보수 용이성: 개별 fragment를 독립적으로 수정하고 테스트할 수 있어 유지보수가 쉬워집니다.
  5. 모듈화: 큰 앱을 작은 조각으로 나눠 관리할 수 있어 복잡성을 줄일 수 있습니다.

주의사항

  • Fragments 내에서 전역 상태를 변경할 때는 주의가 필요합니다. 가능한 한 fragment 내부에서 상태를 관리하거나, 고유한 키를 사용하여 상태를 구분하세요.
  • 복잡한 앱에서는 fragments를 과도하게 사용하면 오히려 앱 구조가 복잡해질 수 있습니다. 적절한 수준에서 fragments를 사용하는 것이 중요합니다.
  • @st.fragment 데코레이터를 사용한 함수는 반환값을 가질 수 없습니다. Fragment는 UI 요소를 직접 렌더링해야 합니다.
  • Fragments 내에서 사용되는 모든 Streamlit 위젯(버튼 등)에는 고유한 key를 지정해야 합니다. 이는 여러 fragment 인스턴스 간의 충돌을 방지합니다.

결론

Streamlit fragments, 특히 st.fragment를 사용한 방식은 앱의 구조를 개선하고 성능을 최적화하는 강력한 도구입니다. 이 간단한 예시에서 볼 수 있듯이, 시계열 데이터 시각화와 기본적인 상호작용 요소를 포함한 대시보드도 fragments를 사용하여 효율적으로 구현할 수 있습니다.

독립적인 상태 관리와 필요한 부분만 재계산하는 특성을 활용하면, 더 효율적이고 유지보수가 쉬운 Streamlit 앱을 개발할 수 있습니다. Fragments의 개념을 잘 이해하고 적절히 사용한다면, 더욱 강력하고 유연한 Streamlit 애플리케이션을 만들 수 있을 것입니다.