FAQ: How to prevent app reruns

Problem

Streamlit operates on a top-down execution model where every widget interaction triggers an app rerun. This occurs whenever user interacts with widget elements such as filling out text/number input box, adjusting values in a slider widget, selecting values in select boxes, etc.

Solution

Here are some ways to prevent this.

1. Use st.form

Embed your widgets in st.form and upon providing the necessary input, users can proceed further by clicking on st.form_submit_button. This simple approach resolves the app rerun issue with every widget interaction as it requires the user to explicitly click on the button to process the widget values.

Consider the following simple example from this blog:

with st.form(key='my_form'):
   text_input = st.text_input(label='Enter some text')
   submit_button = st.form_submit_button(label='Submit')

ezgif.com-video-to-gif-converter

2. Session state

As widget interaction triggers a rerun, but with session state it is possible to have values persist across reruns for instances when you don’t want your variables reinitialized.

In essence, session state variables can be created (if it does not exist) and updated (so that its value is retained after the rerun).

Consider a simple counter example:

# Initialize session state variables
if 'count' not in st.session_state:
   st.session_state.count = 0


# Update session state variables
if st.button('Increment'):
   st.session_state.count += 1

if st.button('Decrement'):
   st.session_state.count -= 1

# Print session state variable
st.write('Count = ', st.session_state.count)

session-state-counter

3. Session state with Callback functions

We can also have widget interactions handled by callback functions. Particularly, when a widget is linked to a callback function, any modification to the widget initiates the following sequence: Firstly, the callback function is executed, next the app runs sequentially from top to bottom.

# Initialize session state variables
if 'count_value' not in st.session_state:
    st.session_state.count_value = 0

# Callback functions
def increment_counter():
    st.session_state.count_value += 1
   
def decrement_counter():
    st.session_state.count_value -= 1

st.button('Increment', on_click=increment_counter, key='increment_btn')
st.button('Decrement', on_click=decrement_counter, key='decrement_btn')

# Print session state variable
st.write('Count = ', st.session_state.count_value)

callbacks-counter


Note:
For all code snippet examples, it is implied that you are implementing the code in a Streamlit app and thus have the necessary import statements in place (e.g. import streamlit as st).

Resources

Demo app that demonstrate examples described herein:

Streamlit Docs:

YouTube tutorials:

Forum posts:

Blog posts: