`st.session_state` values are reset on page reload but `st.cache` values are not

I’m working on an app for labelling records for an ML task. In this app I’m using st.cache to store the data structures that contain the items to annotate and the saved records, and I’m using also session state to track the current iteration (used to retrieve the appropriate item to annotate).

This are working well up until I reload the page. At this point the iteration in the state is reset, however my cached data structures are persisting, which they’re now out of sync: to the user it looks like they have re-started annotation, however the app is remembering their previous decisions.

Ideally the app would either remember its complete synchronised state across st.session_state and st.cache or it would reset both, but only resetting one is a problem.

Is this asymmetric behaviour expected?

Here’s a minimal example that illustrates the behaviour:

import streamlit as st

@st.cache()
def load_data(allow_output_mutation=True):
    return []

def form_callback():
    DATA.append(st.session_state.selection)
    st.session_state.iteration += 1

DATA = load_data()

if "iteration" not in st.session_state:
    st.session_state.iteration = 0

st.write(f"Iteration: {st.session_state.iteration + 1}")

with st.form(key="form"):
    st.selectbox("Choose a Value:", ["value_1", "value_2"], key="selection")
    st.form_submit_button(label="Submit", on_click=form_callback)

st.write(f"previous selections: {DATA}")

I’d use a persistent SQLite DB instead of session state. Reason is, in production, your app shouldn’t really show the clear cache menu option.

Yeah, that makes sense for production. But this app is going to be spun up by data scientists on the command line, so we’re not really going to prod as such for this one.

My current solution that seems to be working is to not use st.cache, and use the st.session_state for everything. So that makes all data being reset (and therefore synced) on page reload now.

1 Like

P.S. You can use SQLite with the :memory: database. Not sure how that behaves with browser refreshes though.

1 Like