streamlit / docs

Source code for the Streamlit Python library documentation
https://docs.streamlit.io
Apache License 2.0
114 stars 469 forks source link

Add info on warning: Calling st.experimental_rerun() within a callback is a no-op #422

Closed evan-wes closed 2 years ago

evan-wes commented 2 years ago

Link to doc page in question (if any): https://docs.streamlit.io/library/api-reference/control-flow/st.experimental_rerun Name of the Streamlit feature whose docs need improvement: st.experimental_rerun What you think the docs should say: I have encountered a puzzling warning using st.button callback functions. The warning states: Calling st.experimental_rerun() within a callback is a no-op.

I can't find any information about this warning except this pull request which appears to implement the warning Make calling st.experimental_rerun() within a callback a no-op which closes this issue: Rerunning the session does not work inside callbacks.

The simple test app I made using the following code triggers this warning (when buttons are pressed in succession) even though st.experimental_rerun is not explicitly run anywhere:

import streamlit as st

def left_callback():
    st.write('Left button was clicked')

def right_callback():
    st.write('Right button was clicked')

left_col, right_col, _ = st.columns([1, 1, 3])

with left_col:
    st.button('LEFT', on_click=left_callback)

with right_col:
    st.button('RIGHT', on_click=right_callback)

It appears that it is an issue with session state and callbacks not properly working together or the app being re-run inside one of the callbacks under the hood.

My suggestion is to add information about possible warnings that st.experimental_rerun() may trigger, including this one I have mentioned. Or add a functionality to suppress the warning. I don't think this is a bug, so I submit this as a documentation improvement in the hopes of getting some answers about why this warning is triggered.

snehankekre commented 2 years ago

Hi @evan-wes 👋 thank you for submitting this issue. I'm unable to reproduce the warning by running your app on Streamlit v1.10.0. Do you have another example that triggers this behavior? If not, we can close this issue.

ks00x commented 2 years ago

I also get this warning message with this demo code in V 1.11: https://gist.github.com/ks00x/7e86dfc968e053a5a00052cc08030119 Without the rerun call , at least page3() in the code does not go back to its previous page as intented. So the code is doing something wheras the warning message suggests otherwise.

BenGravell commented 1 year ago

I ran into this doing a rather naïve thing - trying to expose a "Rerun" button via the following snippet:

st.button("Rerun", use_container_width=True, on_click=st.experimental_rerun)

This was on streamlit 1.23.1.

I know this is redundant and a bit silly considering the Rerun button is exposed via the Streamlit menu in the upper right corner, so not a huge deal.

sametsoekel commented 10 months ago

I’m not sure why a developer really thought that adding an extra unsuppressable warning to a experimental function and wished to inform user with this. I’m using an older version in production and this was the only way I can use. Trying to figure out a way to suppress the yellow warning while knowing this is a no-op.

biclon commented 2 months ago

I agree that the unsuppressable warning is silly. To get around the issue, I did the following:

    display_form: bool = st.session_state['table_form_form_key']['display']
    form_valid: bool = st.session_state['table_form_form_key']['valid']

    if display_form is False and form_valid:  # form validated; show readonly version
        with st.expander(label=f"User Table Information", expanded=False, icon=":material/check_circle:"):
            generate_form_inputs(readonly=True)
            st.session_state['table_form_form_key']['display'] = True

            def rerun():
                # Writing anything to the UI triggers a render of the UI (previously, I was calling st.rerun via the button on_click but that triggered the unsuppressable warning above)
                st.write("")

            st.button("Update Table Information", on_click=rerun) # button to trigger a render of the UI