With streamlit, I am setting a heavy function to cache_data type to avoid recalculation. Since the function is time consuming, I also want to create a progress bar inside it. However, I find the it cannot work with cache_data specified.
The following is a MWE
import streamlit as st
from time import sleep
@st.cache_data(show_spinner = False)
def showProgressBar():
cur = 0
total = 100
my_bar = st.progress(cur / total, text = "%d / %d" % (cur, total))
while cur < total:
sleep(0.05)
cur = cur + 1
my_bar.progress(cur / total, text = "%d / %d" % (cur, total))
my_bar.empty()
### Main ###
st.set_page_config(page_title="Test Progress In Cache Function", page_icon=":bar_chart:",layout="wide")
st.title(" :bar_chart: Test")
showProgressBar()
st.text('Test Finish')
Turn out the bar never shows up with such code. But if I comment out the @st.cache_data line, the progress bar works as expected.
In This thread similar problem is mentioned about progress and st.cache, the workaround seems to be related to suppress_st_warning = True, however with the depreciation of st.cache, this parameter seems no longer available to st.cache_data
Anyone can provide some help here?
If your heavy calculation is
sleep(0.05), here is a way to do it. This piece of code extracts the heavy calculation out of the progress bar handling making sure thecache_datadecorator can be used only on non-Streamlit operations:If however you wanted to keep track of one long function that you call only once, you can convert it to a generator that yields the current step at which the
do_heavy_calcfunction is currently at. I don't recommend this however (it feels a bit hacky), but it seems to work fine in my tests.Two things to note:
cache_datais replaced bycache_resourcesincecache_dataraisesstreamlit.runtime.caching.cache_errors.UnserializableReturnValueError._) in front of the 2 input arguments: this is to ensure that they will not be used for caching purposes. See this streamlit documentation page at section "Excluding input parameters".