Skip some code execution blocks

Hello! Newbie here. Nice to meet you all!

As I understand it, streamlit reruns the app every time a user interacts with a widget. The issue I’m having is that my app runs a dataset analysis that can take 10 secs or more before I can display any data.

I need to be able to skip the analysis upon subsequent runs (i.e. only run when data is uploaded the 1st time or user clicks: ‘Analyze’).

Is there a clean way to stop streamlit from re-running certain blocks of code upon every interaction? Can caching help here?

Thank you!

Hi @Walter-Ullon, welcome to the Streamlit community!

Yes, caching is the behavior you want to use here. Things like loading data, computations and the like where the same input returns the same output are great candidates for caching. If you’re just getting started, I would suggest using st.experimental_memo and st.singleton, as these two are where the library is moving and away from st.cache.

Best,
Randy

Thank you @randyzwitch, I will give that a try!

1 Like

@randyzwitch I tried both decorators for executing my “analysis” function. Here’s what I’m seeing:

  1. upon loading the file with st.file_uploader, the function executes as expected. No issues here.
  2. However, upon interacting with any widget, the analysis executes a second time (undesired behavior)
  3. The function does not execute again after the second time even if I interact with widgets (desired behavior)

My functions are defined as such:

# run and load eda dictionary:
@st.experimental_singleton(show_spinner=False)
def load_dict(uploaded_file):
    if uploaded_file is not None:
        uploaded_file.seek(0)
        eda_data = generate_report(uploaded_file)
    return eda_data
# load dataframe:
@st.experimental_memo(show_spinner=False)
def load_dataframe(uploaded_file):
    if uploaded_file is not None:
        uploaded_file.seek(0)
        eda_df = pd.read_csv(uploaded_file, low_memory=False)
    return eda_df

I step into my code as such:

# file upload:
uploaded_eda_file = st.file_uploader("Upload .csv")

# check if file is uploaded, and if so, run the app:
if uploaded_eda_file is not None:
    # load data and execute:
    with st.spinner('Analyzing data...'):
        df = load_dataframe(uploaded_eda_file)
        data = load_dict(uploaded_eda_file)
    st.success('Done!')

Sorry for the hassle, but where am I going wrong here? Thanks in advance for the help!