to reatin state for normal component like st.selectbox
, we can simply embed code below at the head of every page source script.
for i in st.session_state:
st.session_state[i] = st.session_state[i]
However, when we encounter components like st.data_editor
, an error come out, reads StreamlitAPIException: Values for st.button, st.download_button, st.file_uploader, st.data_editor, st.chat_input, and st.form cannot be set using st.session_state.
We can handle this by following strategy
Step 1 store keys of st.data_editor
in st.session_state.unsupported_keys
in case reloading when switch pages
if 'unsupported_keys' not in st.session_state:
st.session_state.unsupported_keys = []
for i in st.session_state:
if i not in st.session_state.unsupported_keys:
st.session_state[i] = st.session_state[i]
Step 2
- store displayed data in
st.session_state.df_types
- store updated data in
st.session_state.edited_df_types
- store
st.data_editor
’s state inst.session_state.data_dtypes
# dataframe for data_editor to display in the first time
if 'df_types' not in st.session_state:
st.session_state.df_types = df_types
if 'edited_df_types' not in st.session_state:
st.session_state.edited_df_types = df_types
data_dtypes_init = {'edited_rows': [],
'added_rows': [],
'deleted_rows': []}
if 'data_dtypes' not in st.session_state:
st.session_state.data_dtypes = data_dtypes_init
Step 3 Exclude st.data_editor
’s state from updating switching pages.
if 'data_dtypes' not in st.session_state.unsupported_keys:
st.session_state.unsupported_keys.append('data_dtypes')
Step 4 update displayed data as updated data when switch back. the switch back
motion can be recognized by whether st.session_state.data_dtypes
was reset.
if st.session_state.data_dtypes == data_dtypes_init:
st.session_state.df_types = st.session_state.edited_df_types.copy() # update first time displayed dataframe
Step 5 set the displayed data as st.session_state.df_types.copy()
st.session_state.edited_df_types = st.data_editor(st.session_state.df_types.copy(), key='data_dtypes')
Then everything is done!
BUT! This solution is not perfect. the first time the script run, an error raised and click rerun will make everything right. The reason why rerun
is needed still confuse me. I am waiting any answer for this topic