Iām creating a website that shows data regarding a backtest. This isnt the problem though, the problem is that for example, the progress bar says Backtesting (0%)⦠bla blabla. This is because when I create the progress bar, self.progress has 0 as the value. But after some times, self.progress changes value, but for some reason the streamlit website stays the same and it doesnt update the progress bar. This is happening for all the other self attributes that change.
Expected behavior:
Every time a self attribute changes, the data shown should change.
Actual behavior:
Self attributes change but the website stays the same
def _progress(self):
print(f"Progress bar {st.session_state.progress}")
# Progress bar
if "progress_bar" in vars():
self.progress_bar.progress(0, text = f"Backtesting ({st.session_state.progress}%), please wait")
else:
progress_bar = st.progress(st.session_state.progress, text = f"Backtesting ({st.session_state.progress}%), please wait")
But this runs once, and it prints out 0, which is the initial value of st.session_state.progress. So I dont know to be honest whats going on
Iāve lots of files, but hopefully this is enough
I deleted the previous post and now Iām sending this again, I think I was just replying to the post and not directly to you
def _progress(self):
print(f"Progress bar {st.session_state.progress}")
# Progress bar
if "progress_bar" in vars():
self.progress_bar.progress(0, text = f"Backtesting ({st.session_state.progress}%), please wait")
else:
progress_bar = st.progress(st.session_state.progress, text = f"Backtesting ({st.session_state.progress}%), please wait")
This below runs in a thread, but its passed to streamlit.runtime.scriptrunner.add_script_run_ctx
Iām investigating the behavior of other functions and it seems to me that self attributes are not being recognized along the script, no idea why this is the case. Iāve no problem on sharing my whole code, its not much, but I doubt you want to read all the code
This is getting a bit frustrating to be honest. Can I be sure that if self attributes or st.session_state attributes change, the website will update what it shows?
Do I need to add an extra piece of code for this to happen?
I suspect what @Goyo said is right, and there is probably a mistake in your code. I would recommend trying to strip your code down to just the progress bar and see if you can get it working, and then slowly build back up.
That being said, hereās a simple example of an object using its own attribute to update a progress bar
from dataclasses import dataclass
from time import sleep
from typing import Any
import streamlit as st
@dataclass
class Program:
progress_bar: Any
progress: int = 0
def increment(self):
self.progress += 1
self.update_progress_bar()
def update_progress_bar(self):
self.progress_bar.progress(self.progress, text=f"Progress: {self.progress}%")
my_bar = st.progress(0, text="Operation in progress. Please wait...")
p = Program(progress_bar=my_bar)
while p.progress < 100:
p.increment()
sleep(0.1)
So, thereās no inherent reason why it canāt work.
In one sense, not very much in streamlit is āautomaticā. It just runs like a script, from top to bottom. If you call bar.progress with a new value, it will be updated. But, it doesnāt automatically get updated just because the first value you passed to it changes.
For example, this doesnāt work:
x = 10
bar = st.progress(x)
x = 100
The bar will not automatically get updated to 100, even though the value of the initial variable changed. You would have to actually call bar.progress(x) to update it.
Then I guess my best option would be just rerunning the website again every time data updates, cause there are lots of variables changing, each variables is used in a different component, and idk how easy (not even how to) it is to update (not rerunning the website) for example, a manually created markdown table, text, etc.
For example:
def _status(self):
st.markdown(f"The current status of the backtest is: **:{self.status_color}[{self.status}]**")
st.markdown(f"The estimated time to finish the backtest is **{self.eta}**.")
There is no such way to update this right? I need to rerun the website?
[EDIT]
Sorry for all the questions Iām just trying to figure out how can I get to update my website as variables change. And thanks for all the help you are giving me.
If nothing else, you can call st.experimental_rerun() to force the script to rerun.
However, if you interact with a widget the whole script is rerun, which typically means you shouldnāt need to use experimental_rerun. If something is happening behind the scenes that is changing a variable, then it gets more tricky, and you may need to use experimental_rerun.
If you have a simple case like this:
x = st.slider("Pick a number")
st.write(x)
then the app will update automatically as the slider changes.