Avoid running code within an expander if it's collapsed

Currently, it seems that code within an expander is run every time the script is rerun, regardless of whether it’s collapsed or expanded, which is definitely very useful in a lot of circumstances, but I was wondering if this could be turned off in any way, for example to avoid performing expensive computation if the user isn’t interested in the result.

Is there maybe a way to access the state of the expander, so that you can tell programmatically whether it’s expanded or collapsed at any given time (then conditionally perform the computation)? Otherwise, would it be possible to add an option in the expander to disable the code within the expander when it’s collapsed?

Below is a simple example of the kind of thing I was trying to accomplish. For now, I’m just using a checkbox to enable/disable the computation, but of course the expander is a lot nicer, so it would be great to be able to achieve this with the expander.

import streamlit as st
import numpy as np
import time

@st.cache()
def get_images():
    return np.random.random((10,300,300,3))

@st.cache()
def do_expensive_computation(image):
    time.sleep(3)
    return image

images = get_images()
num = st.slider('Image number', min_value=1, max_value=images.shape[0])

col1, col2 = st.beta_columns(2)

with col1:
    st.subheader('Image')
    st.image(images[num-1])

with col2:
    result_expander = st.beta_expander('Optional result', expanded=False)
    with result_expander:
        # ideally only execute this code when expanded
        result = do_expensive_computation(images[num-1])
        st.image(result)

Thanks!

1 Like

Hey @smehra34,

Welcome to the Streamlit Community! :tada: :tada: :partying_face: :partying_face: :tada: :partying_face: :tada: :partying_face:

So by the nature of the st.beta_expander(), it does not re-run your code at all. The kinda general purpose for the expander is to simply display additional things that you don’t want cluttering up your app. But becasue it doesn’t run any code when you expand it, your additional code would never actually get run.

My suggestion is to make that a button that runs the function and displays your image after you click it.

with col2:
    result= st.button('Optional result')
    if result:
        # ideally only execute this code when expanded
        result = do_expensive_computation(images[num-1])
        st.image(result)

gives:

once you click the button it actually runs your code and displays:

Happy Streamlit-ing!
Marisa

1 Like

Ahh I see, thanks @Marisa_Smith for the explanation! I didn’t even notice that the app wasn’t getting rerun when using the expander, but that makes a lot of sense.

Also thanks for all the awesome work you guys have been doing with Streamlit! Especially with the recent updates, it’s amazing to be able to write such nice apps in such little time.

2 Likes

No problem!

So glad you like it! We love to make apps easy for the community :partying_face::star_struck: