Skip to content

Instantly share code, notes, and snippets.

@okld
Last active September 25, 2023 13:50
Show Gist options
  • Star 61 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save okld/0aba4869ba6fdc8d49132e6974e2e662 to your computer and use it in GitHub Desktop.
Save okld/0aba4869ba6fdc8d49132e6974e2e662 to your computer and use it in GitHub Desktop.
Streamlit - Settings page with session state
import streamlit as st
from persist import persist, load_widget_state
def main():
if "page" not in st.session_state:
# Initialize session state.
st.session_state.update({
# Default page.
"page": "home",
# Radio, selectbox and multiselect options.
"options": ["Hello", "Everyone", "Happy", "Streamlit-ing"],
# Default widget values.
"text": "",
"slider": 0,
"checkbox": False,
"radio": "Hello",
"selectbox": "Hello",
"multiselect": ["Hello", "Everyone"],
})
page = st.sidebar.radio("Select your page", tuple(PAGES.keys()), format_func=str.capitalize)
PAGES[page]()
def page_home():
st.write(
f"""
Settings values
---------------
- **Input**: {st.session_state.text}
- **Slider**: `{st.session_state.slider}`
- **Checkbox**: `{st.session_state.checkbox}`
- **Radio**: {st.session_state.radio}
- **Selectbox**: {st.session_state.selectbox}
- **Multiselect**: {", ".join(st.session_state.multiselect)}
"""
)
def page_settings():
st.header("Change settings")
st.text_input("Input", key=persist("text"))
st.slider("Slider", 0, 10, key=persist("slider"))
st.checkbox("Checkbox", key=persist("checkbox"))
st.radio("Radio", st.session_state["options"], key=persist("radio"))
st.selectbox("Selectbox", st.session_state["options"], key=persist("selectbox"))
st.multiselect("Multiselect", st.session_state["options"], key=persist("multiselect"))
PAGES = {
"home": page_home,
"settings": page_settings,
}
if __name__ == "__main__":
load_widget_state()
main()
from streamlit import session_state as _state
_PERSIST_STATE_KEY = f"{__name__}_PERSIST"
def persist(key: str) -> str:
"""Mark widget state as persistent."""
if _PERSIST_STATE_KEY not in _state:
_state[_PERSIST_STATE_KEY] = set()
_state[_PERSIST_STATE_KEY].add(key)
return key
def load_widget_state():
"""Load persistent widget state."""
if _PERSIST_STATE_KEY in _state:
_state.update({
key: value
for key, value in _state.items()
if key in _state[_PERSIST_STATE_KEY]
})
@Jacobrsmith37
Copy link

Thanks for this! Works great for me.

I'm trying to edit the code so that I can persist a session state of an editable dataframe while navigating between different pages of the app. I'm using AgGrid to make the df editable, but when refreshing or going to another page, the df defaults back to original values. Do you have any suggestions on how to implement this from your code above? I've been stuck on this for a week now

@lluissalord
Copy link

@okld Really nice work. However, I see that for refreshing is not working anymore. Do you have any idea of how to handle it?

@EqualAPriori
Copy link

Really neat concept! Does this only work if you have a main script registering and driving the different pages?

I tried this persist/load_widget_state() approach on a multi-page app using the current directory structure of implementing multipage apps, and it didn't work for me.

@Stachys
Copy link

Stachys commented Sep 25, 2023

Hey man, many thanks for this snippet!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment