if 'your_number' not in st.session_state:
= None st.session_state.your_number
36 Persisting Data Across Pages and Runs with Session State
One limitation we’ve mentioned of multipage apps is that variables do not persist across the different pages.
Once you switch pages, all of that information is lost!
However - you can use session state to remember things across multiple pages or multiple runs of the same app.
It doesn’t help with remembering information when leaving or fully reloading the page.
36.1 Initialising session state keys
First, we need to initialise the session state key with a default value if it doesn’t already exist.
This can be anything, and doesn’t strictly have to be the same type of data as the final value will be - though it’s usually good practice to keep it fairly consistent throughout its lifecycle!
You need to do this on every page of your app where you will do either of the following:
- Update the value
- Display the value
36.2 Assigning to session state keys
Session state can be used to store a range of things.
It can store the input given in a user input widget:
= st.number_input(
st.session_state.your_number "Pick a number between 1 and 100",
=1, max_value=100, value=None
min_value )
This is the simplest way to assign a user’s input to the session state to pass it around between pages or something along those lines.
However - you will need to be mindful of what default value you initialise the input with using the value
parameter. It will automatically overwrite the session state key as soon as the page containing the input widget is opened.
Later, we cover the concept of callbacks
; the on_change
parameter that is available for most streamlit inputs will allow you to use a callback function to update the session state only after the first time the user interacts with the widget, which can be better depending on your app.
Or the result of a calculation (whether that’s a number, a dataframe, a graph, or something else)
= result * 42 st.session_state.the_final_answer
The thing you’re saving to the state could itself optionally use something stored in the session state!
= st.session_state.your_number * 42 st.session_state.the_final_answer
36.3 Using the session state
You can then access the session state key regardless of the page you are using it on!
Just remember - you need to check for whether the key exists in the session state anywhere you are setting or using the key, and set a default value for it if it doesn’t already exist.
When your app is deployed, a user could open the app on a page that means they are trying to view the stored session state key before they’ve had a chance to actually input a value - so think about how you could use conditional logic (if/elif/else) to handle this gracefully.
36.4 A more complex multipage example
Let’s now take a look at a full example across several pages that makes use of session state.
Here, we’ll have a numeric input that makes use of session state.
We’ll have a text input for the user’s name which doesn’t make use of session state.
Try comparing the behaviour when moving between the different pages of the app.
36.4.1 app.py
import streamlit as st
= st.navigation([
pg "page_1.py", title="Start here!"),
st.Page("page_2.py", title="Now go here")
st.Page(
])
pg.run()
36.4.2 page_1.py
import streamlit as st
if 'your_number' not in st.session_state:
= None
st.session_state.your_number if 'the_final_answer' not in st.session_state:
= None
st.session_state.the_final_answer
"Session State Example")
st.title(
= st.number_input(
st.session_state.your_number "Pick a number between 1 and 100",
=1, max_value=100, value=None
min_value
)
if st.session_state.the_final_answer is None:
"Enter a number and then go to the next page to calculate the final answer"
else:
f"Your answer is {st.session_state.the_final_answer} - but what was the question?"
st.divider()
= st.text_input("Enter Your Name") name_input
36.4.3 page_2.py
import streamlit as st
if 'your_number' not in st.session_state:
= None
st.session_state.your_number if 'the_final_answer' not in st.session_state:
= None
st.session_state.the_final_answer
if st.session_state.your_number is None:
"Go back to the previous page and enter a number!")
st.write(else:
f"I remember your number! It's {st.session_state.your_number}")
st.write(
= st.session_state.your_number * 42
st.session_state.the_final_answer "I've calculated the final answer and put it back on the first page...")
st.write(
st.divider()
"Your name? Let me look up what your name is.")
st.write(
try:
st.write(name_input)except:
"I don't seem to remember your name...") st.write(
The sample app linked below also uses a concept known as callbacks
, which is often used with session state, to make the button increment work. Head to the callbacks chapter to find out more!