- I run the app locally
streamlit version: 1.29.0
python version 3.11.4
I am trying to do the following simple app:
I connect to a broker api to get prices; i receive those prices in a separate thread in that brokers api library implementation. When this happens i want to trigger a script rerun so that the GUI updates
To simulate it I’m using this code:
import streamlit as st
import threading
import time
from streamlit.runtime.scriptrunner import add_script_run_ctx
print('streamlit_thread({}): =====> script run started'.format(threading. get_ident()))
class Data:
lock_last_price = threading.Lock()
last_price = 0
@st.cache_resource
def get_storage():
return Data()
def generate_last_price():
while(True):
with get_storage().lock_last_price:
get_storage().last_price += 1
print('background_thread({}): last_price {}'.format(threading. get_ident(), get_storage().last_price))
print('background_thread({}) sleep 1 sec'.format(threading.get_ident()))
time.sleep(1)
st.rerun()
@st.cache_resource
def start_singleton():
print('streamlit_thread({}): -----> start_singleton only once'.format(threading. get_ident()))
t = threading.Thread(target=generate_last_price, daemon=True)
add_script_run_ctx(t)
t.start()
print('streamlit_thread({}): <----- start_singleton only once'.format(threading. get_ident()))
start_singleton()
streamlit_last_price = 0
with get_storage().lock_last_price:
streamlit_last_price = get_storage().last_price
print('streamlit_thread({}): last_price {}'.format(threading. get_ident(), streamlit_last_price))
st.text(streamlit_last_price)
print('streamlit_thread({}): <===== script run finished'.format(threading. get_ident()))
Sample run:
streamlit_thread(17612): =====> script run started
streamlit_thread(5964): =====> script run started
streamlit_thread(5964): -----> start_singleton only once
streamlit_thread(5964): <----- start_singleton only once
background_thread(48768): last_price 1
background_thread(48768) sleep 1 sec
streamlit_thread(5964): last_price 1
streamlit_thread(37096): =====> script run started
streamlit_thread(5964): <===== script run finished
streamlit_thread(37096): last_price 1
streamlit_thread(37096): <===== script run finished
streamlit_thread(17612): last_price 1
streamlit_thread(17612): <===== script run finished
streamlit_thread(35928): =====> script run started
streamlit_thread(35928): last_price 1
streamlit_thread(35928): <===== script run finished
background_thread(48768): last_price 2
background_thread(48768) sleep 1 sec
background_thread(48768): last_price 3
background_thread(48768) sleep 1 sec
background_thread(48768): last_price 4
background_thread(48768) sleep 1 sec
background_thread(48768): last_price 5
background_thread(48768) sleep 1 sec
background_thread(48768): last_price 6
background_thread(48768) sleep 1 sec
background_thread(48768): last_price 7
background_thread(48768) sleep 1 sec
streamlit_thread(1224): =====> script run started
streamlit_thread(1224): last_price 7
streamlit_thread(1224): <===== script run finished
streamlit_thread(53844): =====> script run started
streamlit_thread(53844): last_price 7
streamlit_thread(53844): <===== script run finished
background_thread(48768): last_price 8
background_thread(48768) sleep 1 sec
background_thread(48768): last_price 9
The problem I get is that the script rerun does not get triggered from the background thread. The UI does not update and in the st.text value i see an old value (not synced with background_thread)
Any help on this? I can’t find where the bug is. Or if you have any other architecture changes/suggestions on what might be wrong?