Button not disappearing when the page refreshes with long-running function

Hi there:

I’m running a streamlit app locally, using Python 3.11.7 and streamlit 1.42.2.

My problem is that when a page reload triggers a long running process, the button that caused the process to kick-off doesn’t disappear while the long-running process is running. Even worse, it stays active and can be clicked while the progress bar is updating.

Here’s a minimal fully working app that displays the problem

import streamlit as st
import time

print('App-rerun')

if st.session_state.get('btn_run', False):
    progress = st.progress(0)
    for i in range(5):
        progress.progress((i+1)/5)
        time.sleep(1)

    st.write('Done')
else:
    st.write('Lots of text')
    st.write('More text here')
    btn_run = st.button('Run', key='btn_run')

When you click on the button, it remains visible while the progress bar is updating. How can I fix this?

Thanks!

FYI, in case anyone comes upon this thread, I solved this by using a multipage app… Though I’d still love to know if it’s solvable on a single page app!

import streamlit as st
import time

def first_page():
    st.write('Lots of text')
    st.write('More text here')
    st.write('More text here')
    st.write('More text here')
    st.write('More text here')
    st.write('More text here')
    st.write('More text here')
    st.write('More text here')
    st.write('More text here')
    btn_run = st.button('Run')

    if btn_run:
        st.switch_page(p2)

def second_page():
    progress = st.progress(0)
    for i in range(5):
        progress.progress((i+1)/5)
        time.sleep(1)

    st.write('Done')

p1 = st.Page(first_page, title='p1')
p2 = st.Page(second_page, title='p2')

pg = st.navigation([p1, p2], position='hidden')

pg.run()

This comes up a lot with chat layouts and with spinner/progress elements. You can use containers and/or empties to clear the elements. Here’s another thread about it. (Not exactly the same scenario. Let me know if it’s not clear.) Streamlit Spinner and Chat Message odd interaction - #2 by mathcatsand

When Streamlit reruns, it replaces elements one at a time. (The first element rendered in the rerun replaces the first element from the previous one.) During this process all other elements on the page are in a stale state while Streamlit waits to get through the script. Only at the end of the script run will it discard any leftover stale elements.

Containers and empties given you a way to ensure there is not some nth element sitting on your page during a script run, waiting to find out it’s not getting replaced.