I’m just learning streamlit so i created a toy app that implements a simple timer. The code (see below) uses ‘rerun’ to update the progress of the countdown
I noticed that with long timers after ~16 min the app stops and only the title ‘Timer Demo’ is displayed
I assume this is something I am doing wrong due to my lack of understanding of the framework
Here is the stack trace
Here is the code:
import streamlit as st
import time
import os
DEFAULT_TIMER=1500
# Initialize session state variables
if 'timer_seconds' not in st.session_state:
st.session_state.timer_seconds = DEFAULT_TIMER
if 'time_remaining' not in st.session_state:
st.session_state.time_remaining = DEFAULT_TIMER
if 'timer_state' not in st.session_state:
st.session_state.timer_state = 'idle'
# Timer control functions
def start_timer():
if st.session_state.timer_state == "idle":
st.session_state.time_remaining = st.session_state.timer_seconds
st.session_state.timer_state = "running"
def pause_timer():
st.session_state.timer_state = "paused"
def reset_timer():
st.session_state.timer_state = "idle"
st.session_state.time_remaining = st.session_state.timer_seconds
def progress_update():
# Progress bar
st.progress(st.session_state.time_remaining / st.session_state.timer_seconds)
st.text(f'{st.session_state.time_remaining}s remaining')
time.sleep(1)
def sound_alert():
try:
# works on macOS
os.system( "say 'times up!'" )
except:
pass
# App layout
st.title("Timer Demo")
# User sets the timer
st.session_state.timer_seconds = st.number_input("Set timer (in seconds):", min_value=0,
value=st.session_state.timer_seconds, key="set_timer")
# Timer buttons
col1, col2, col3 = st.columns(3)
with col1:
st.button("Start", on_click=start_timer)
with col2:
st.button("Pause", on_click=pause_timer)
with col3:
st.button("Reset", on_click=reset_timer)
# Timer logic
if st.session_state.timer_state == "running":
if st.session_state.time_remaining > 0:
progress_update()
st.session_state.time_remaining -= 1
st.rerun()
else:
st.session_state.timer_running = False
st.balloons()
sound_alert()
reset_timer()
elif st.session_state.timer_state == "paused":
progress_update()
st.rerun()
Full stack trace:
Exception in thread ScriptRunner.scriptThread:
Traceback (most recent call last):
File "/Users/rupert/scratch/togalit/venv/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 535, in _run_script
exec(code, module.__dict__)
File "/Users/rupert/scratch/togalit/src/togalit/timer.py", line 53, in <module>
st.session_state.timer_seconds = st.number_input("Set timer (in seconds):", min_value=0,
File "/Users/rupert/scratch/togalit/venv/lib/python3.10/site-packages/streamlit/runtime/metrics_util.py", line 397, in wrapped_func
result = non_optional_func(*args, **kwargs)
File "/Users/rupert/scratch/togalit/venv/lib/python3.10/site-packages/streamlit/elements/widgets/number_input.py", line 237, in number_input
return self._number_input(
File "/Users/rupert/scratch/togalit/venv/lib/python3.10/site-packages/streamlit/elements/widgets/number_input.py", line 300, in _number_input
int_args = all(
File "/Users/rupert/scratch/togalit/venv/lib/python3.10/site-packages/streamlit/elements/widgets/number_input.py", line 301, in <genexpr>
isinstance(a, (numbers.Integral, type(None), str))
File "/usr/local/Cellar/python@3.10/3.10.13_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/abc.py", line 119, in __instancecheck__
return _abc_instancecheck(cls, instance)
File "/usr/local/Cellar/python@3.10/3.10.13_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/abc.py", line 123, in __subclasscheck__
return _abc_subclasscheck(cls, subclass)
RecursionError: maximum recursion depth exceeded in comparison
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
<snipped>
"/usr/local/Cellar/python@3.10/3.10.13_2/Frameworks/Python.framework/Versions/3.10/lib/python3.10/traceback.py", line 353, in extract
limit = getattr(sys, 'tracebacklimit', None)
RecursionError: maximum recursion depth exceeded while calling a Python object