Summary
Dear Streamlit Community,
I’ve encountered an issue with my Streamlit application that I would greatly appreciate your input on.
In this application, I am running a while
loop to update the stream of a camera. While running this loop, I want to allow the user to interact with a button to perform a certain action. However, I noticed that when the loop is running, the button becomes unresponsive. I suspect this is due to the loop blocking the rest of the application’s execution.
Steps to reproduce
To run the code, please set fastReruns to false, otherwise you may face st.session_state issues:
streamlit run minimal_example.py --runner.fastReruns False
Code snippet:
import time
import streamlit as st
def minimal_example():
if 'is_streaming' not in st.session_state:
st.session_state.is_streaming = False
if 'counter' not in st.session_state:
st.session_state.counter = 0
def start_stream():
if st.button("Start Streaming"):
st.session_state.is_streaming = True
text_placeholder = st.empty()
while st.session_state.is_streaming:
text_placeholder.text(f"Streaming {st.session_state.counter }")
st.session_state.counter += 1
time.sleep(1)
def button_function():
if st.button("Test Button"):
st.text("Clicked")
start_stream()
button_function()
minimal_example()
Expected behavior:
Test button should stay enabled.
Actual behavior:
Test button disabled.
Debug info
- Streamlit version: 1.25.0
- Python version: 3.9.9
- Using PyCharm
- OS version: Windows 11
- Browser version: Chrome Version 115.0.5790.17
Additional information
- I attempted to use a separate thread for the stream, but it appears that the created thread does not communicate with the main thread. However, the prints show that the new thread is running:
import time
import streamlit as st
import threading
from streamlit.runtime.scriptrunner import add_script_run_ctx
def minimal_example_2():
if 'thread_started' not in st.session_state:
st.session_state.thread_started = False
if 'counter' not in st.session_state:
st.session_state.counter = 0
def start_stream():
if st.button("Start Streaming") and not st.session_state.thread_started:
st.session_state.thread_started = True
start_updating(text_placeholder)
def start_updating(placeholder):
thread = threading.Thread(target=update_counter, args=(placeholder,),
daemon=True)
add_script_run_ctx(thread)
thread.start()
def update_counter(placeholder):
while st.session_state.thread_started:
placeholder.write(f"Streaming = {st.session_state.counter}")
st.session_state.counter += 1
print(
f"New Thread is increasing the streaming to: {st.session_state.counter}")
time.sleep(1)
def stop_stream():
if st.button("Stop Streaming"):
st.session_state.thread_started = False
def button_function():
if st.button("Test Button"):
st.text("Clicked")
text_placeholder = st.empty()
start_stream()
stop_stream()
button_function()
minimal_example_2()
If any of you have come across a similar situation or have any ideas on how I can address this problem, I would be very grateful for your suggestions.
Thank you in advance for your time and insights!