고민은 격렬하게, 행동은 단순하게

[Streamlit] 변수를 기억하고 싶다면 Session State를 사용하십시다. 본문

개발

[Streamlit] 변수를 기억하고 싶다면 Session State를 사용하십시다.

jomminii 2024. 1. 26. 18:30

streamlit

 

이전 글(AWS Polly(폴리)를 이용한 TTS(Text To Speech, 음성 합성) 구현 (3))에서 Streamlit과 AWS Polly를 사용해서 음성 합성 서비스를 구현해 봤는데요. 이때 아쉬웠던 것 중 하나가 aws key 들을 각 페이지를 넘어 다닐 때마다 새로 입력해줘야 하는 거였어요.

 

Streamlit이 재실행(rerun) 됐을 때나 페이지를 넘어 다닐 때 저장된 변수들의 상태가 유지되지 않기 때문인데요, 이를 위해 Streamlit에서는 Session State 기능을 제공합니다.

Streamlit의 세션이란?

We define access to a Streamlit app in a browser tab as a session. For each browser tab that connects to the Streamlit server, a new session is created. Streamlit reruns your script from top to bottom every time you interact with your app. Each reruns takes place in a blank slate: no variables are shared between runs.

브라우저 탭을 각각의 세션으로 접근하고 있으며, 앱과 상호작용을 할 때마다 모든 스크립트가 재실행됩니다. 재실행은 순식간에 일어나며, 모든 변수들은 공유되지 않아요.
- Streamlit docs

 

 

Session State 관련 Docs

 

Streamlit 은 Session에 내가 저장하고 싶은 변수들을 기억할 수 있게 Session State 기능을 제공해요.

 

 

# 사용법

간단한 사용법을 먼저 알아볼게요.

 

# 초기화
if 'aws_key' not in st.session_state:
    st.session_state = ['aws_key'] = 'ABCDEFGHIJ...'
	
    or
    
    st.session_state.aws_key = 'ABCDEFGH...'
    
    
# 조회
st.write(st.session_state['aws_key'])

or

st.write(st.session_state.aws_key)

-> ABCDEFGH


# 업데이트
st.session_state.aws_key = 'FFFAAASSS'

# session_state의 모든 값 조회
st.write(st.session_state)

-> 
{
  "aws_key": "FFFAAASSS"
}

# 단 건 삭제
del st.session_state['aws_key']

# 세션 내 모든 데이터 삭제
for key in st.session_state.keys():
    del st.session_state[key]
    
or

st.session_state.clear()

 

사용법은 간단해요. dictionary에 값을 부여하고, 조회하는 것과 동일하게 작동합니다. 일반적으로 input으로 텍스트 등을 받아서 값을 저장하는 방식으로 사용하는데요, 예를 들어 text input으로 텍스트를 받고, 저장 버튼을 눌러 session에 저장하는 방식입니다.

 

input = st.text_input("aws_key")

st.button("Save to Session State", on_click=lambda: st.session_state.update({"aws_key": input}))
st.button("Clear Session State", on_click=lambda: st.session_state.clear())


st.write(st.session_state)

 

텍스트 창에 값을 넣고, 저장 버튼을 누르면 on_click 이벤트가 발생됩니다. 이때 이벤트에 콜백 람다를 전달해 세션에 값을 저장합니다.

저장된 값을 삭제하고 싶을 때는 동일하게 버튼을 생성해서 st.session_state.clear() 람다를 작동하게 하면 됩니다.

 

 

 

이 외에도 UI 상의 Clear cache를 이용해도 지울 수 있어요!

 

 

 

세션에 값을 넣는 또 다른 방법은 데이터를 받는 input 컴포넌트에 세션에 저장할 키를 매핑하는 거예요. 

 

st.text_input("aws_key", key="aws_key")

st.button("Clear Session State", on_click=lambda: st.session_state.clear())

st.write(st.session_state)

 

st.text_input에 session_state의 key를 매핑해 주면, 자동으로 session_state의 해당 키에 값이 매핑됩니다. 근데 타이핑을 할 때마다 매핑이 되진 않고, 다른 상호작용 이벤트를 발생시켜야 적용이 되는 점은 참고해 주세요!

 

예를 들어, 다른 요소를 클릭하거나 하는 등의 추가적인 이벤트가 필요해요.

 

 

# 기존 프로젝트에 적용

이제 기존에 만들었던 프로젝트에 aws key 관련 정보를 입력받은 후 세션에서 유지시키는 작업을 해볼 건데요.

여러 페이지에서 공용으로 쓸 컴포넌트라 공통 컴포넌트용 디렉터리를 따로 따서 진행했어요.

 

경로는 project_dir> component> side_bar.py로 만들어줬고요.

 

 

 

구현 코드는 아래와 같습니다.

def aws_credentials_sidebar():
    access_key_in_session = st.session_state.get("access_key")
    secret_access_key_in_session = st.session_state.get("secret_access_key")

    with st.sidebar:
        if not access_key_in_session:
            access_key = st.text_input(
                "Write down an AWS ACCESS KEY",
                placeholder="AWS ACCESS KEY",
            )
        else:
            access_key = access_key_in_session

        if not secret_access_key_in_session:
            secret_access_key = st.text_input(
                "Write down an AWS SECRET ACCESS KEY",
                placeholder="AWS SECRET ACCESS KEY",
            )
        else:
            secret_access_key = secret_access_key_in_session

	# key 정보가 저장되지 않았으면 저장 버튼 노출
        if not (access_key_in_session and secret_access_key_in_session):
            st.button(
                label="Save Key",
                on_click=lambda: st.session_state.update(
                    {"access_key": access_key, "secret_access_key": secret_access_key}
                )
            )

	# key 정보가 저장되어 있으면 초기화 버튼 노출
        if access_key_in_session and secret_access_key_in_session:
            st.button(
                label="Clear Key",
                on_click=lambda: st.session_state.clear()
            )

        return access_key_in_session, secret_access_key_in_session

 

sidebar 컴포넌트 아래에 aws key 정보를 받을 수 있는 text_input 컴포넌트들을 만들고, 세션에 해당 정보들이 저장되어있지 않은 상태일 때 저장 버튼을 노출시켰어요. 그리고 정보가 모두 저장된 상태일 때는 값을 초기화할 수 있는 버튼을 제공해서 편의를 제공했습니다.

 

 

이제 사용량 조회를 위해 다른 페이지로 넘어가도 키 정보가 그대로 유지되서 편리해졌어요! 점점 더 발전하는 프로젝트...

 

해당 코드는 github 에서도 확인하실 수 있어요!

 

 

# 참고

- Session State - Streamlit Docs

- Add statefullness to apps - Streamlit Docs

 

 

반응형