Streamlit buttons not resetting state when a for loop is running

Summary

Iโ€™m trying to create real time monitoring and control dashboard using streamlit following this tutorial: How to build a real-time live dashboard with Streamlit
This works well for the monitoring part, but Iโ€™m also trying to add buttons to do things like a http post.
When i add multiple buttons, every time i press a button all previously pressed buttons get pressed too, which does not make sense as streamlit should rerun after every interaction and should not keep the state of buttons. I noticed this behaviour happen because a for loop is present, which is needed for the real time dashboard as per the tutorial for refreshing the graphs and loading the data.

Steps to reproduce

Code snippet:

import streamlit as st
import time

                            
if st.button("Test 1", key='test_1'):
    print(1)

if st.button('test 2', key='test 2'):
    print(2)

def generate_graph():
    # Continuously generate/update the graph

    while True:
        time.sleep(1)
        # st.write(datetime.now())


def main():

    generate_graph()


if __name__ == '__main__':
    main()

When pressing button 1 it will print 1. When pressing 2 after this both 1 and 2 will be printed.

Expected behavior:

Streamlit does the button action stated in the if and reruns not remembering old state.

Actual behavior:

Streamlit does button action stated in the if of the pressed button and all previously pressed buttons.

Debug info

  • Streamlit version: 1.23.1
  • Python version: 3.11
  • Using Conda

Requirements file

streamlit==1.23.1

Additional information

Pressing the clear cache button in the hamburger menu fixes this problem, but i did not find a way to programmatically do this action after every rerun.

There are a couple open issues for this one (or at least issues that I think may play a role here):

Try doing these two things:

  1. In your config file (create one if you arenโ€™t using one yet), set:
[runner]
 fastReruns = false
  1. Add some frontend Streamlit command into your infinite loop (if you donโ€™t have already)
while True:
    time.sleep(1)
    st.write('')

Or:

foo = st.empty()
while True:
    time.sleep(1)
    foo.write('')

This behaves as expected (with fastRerun disabled)

import streamlit as st
import time

st.write(st.session_state)
                            
st.button("Test 1", key='test_1')

st.button('test 2', key='test 2')

st.write(st.session_state)

while True:
    time.sleep(1)
    st.write('')

This also behaves as expected (with fastRerun disabled)

import streamlit as st
import time
                            
if st.button("Test 1", key='test_1'):
    print(1)

if st.button('test 2', key='test 2'):
    print(2)

def generate_graph():
    foo = st.empty()
    while True:
        time.sleep(1)
        foo.write('')

def main():
    generate_graph()

if __name__ == '__main__':
    main()
1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.