I am working on an app where the user can choose via a multiselect tool what months he wants to and via a drop down what customer he is interested in. However, whenever the page is refreshed, these selections are gone and he needs to choose everything again. I have come across the topic of session_state and callback but finding it impossibly difficult to understand. I have read quite a few articles, watched videos and tried out code but I just don’t get it. How can one store the user selections so they remain in place after a refresh?
Some widgets (like buttons) cause a streamlit refresh (re-running of code from the top)
In such a scenario, if you have a variable:
a. initially set to a certain value, and
b. later change the variable value, and
c. press the widget that causes a refresh
your variable will again start with its initial defined value
If you want a variable to persist its value across refreshes, you need to define it as a session state variable by the statement: if "my_variable_name" not in st.session_state: st.session_state.my_variable_name = "xyz"
This records the variable in the program’s session state and initializes it to the value ‘xyz’
Future changes to that variable in your code must be made by the statement: st.session_state.my_variable_name = "pqr"
Now the variable will have its last assigned value across refreshes (i.e pqr).
Callbacks are functions that can be associated with widgets. If a widget has a defined callback, then whenever the value of the widget is changed by the user, the callback is first called, to process whatever code is within it.
Hi Shawn, many thanks for getting back so quickly. I have prepared a very simple code that is I think in line with what you mean. However, I am missing something as it isn’t yet retaining the value when I press the reload button. This is the code:
import streamlit as st
from streamlit_js_eval import streamlit_js_eval
my_variable_name = st.sidebar.multiselect("Test", {'xyz','pqr'})
st.write(my_variable_name)
if st.button("Reload page"):
streamlit_js_eval(js_expressions="parent.window.location.reload()")
if my_variable_name not in st.session_state:
st.session_state.my_variable_name = 'pqr'
st.session_state.my_variable_name = 'xyz'
When I press the reload button, the multiselect is once again blank, rather than having the value that I last selected in it. So, if I select ‘pqr’ and then press the reload button, it goes back to being blank, rather than it showing the ‘pqr’ value. I have also tried to position the reload button code at the end, thinking it might have something to do with the cadence of the code but this changed nothing at all.
Sorry, I realise this must be quite elementary, trivial even - I hope it will become second nature one day.
If you’re pressing the browser reload button, it triggers a new session, so using session state is no good if that’s the case.
If that’s the case you would have to use a database technology such as MongoDB, Firestore or others to save the user’s selections, and fetch it everytime the user reloads the app.
Oh Gosh! I guess the issue is that we will have quite a lot of users that are interacting with the app, so it sounds quite complicated to need to save the variable to a database. The reason I have a reload button in my app is because once they input something in an editable grid, it then needs to rerun a relatively complex calculation in python. And unless the page is reloaded, it doesn’t seem to rerun that calculation. Is there another way of reloading without triggering a completely new session then?
Hi again. I have just realised something: rather than the button causing a reload and thus a complete new session, I could try and see if I can cause it to “re-run” instead. This might sound like the same thing, but it isn’t. I have tried out to cause the app to simply re-run and the script / calculation is still triggered but the it doesn’t create a sesion. So now the only question is, how do I cause a rerun rather than a reload
Yes, that’s pretty much it. Remember you can also save lists on st.session_state if needed, such as:
import streamlit as st
# Define your options
options = ['A', 'B', 'C']
# Initialize selected options on your session state
if 'selected_options' not in st.session_state:
st.session_state['selected_options'] = []
# The widget to select your options
selected_options = st.sidebar.multiselect("Test",
options=options,
default=st.session_state['selected_options'])
# Save the selected options on your session state
st.session_state['selected_options'] = selected_options
# Write the objects saved on your session state
st.write(st.session_state['selected_options'])
# Reload page
if st.button("Reload page"):
st.rerun() # st.experimental_rerun() is not experimental anymore in latest Streamlit versions
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.