Hi there, I have three progress bars that are starting asynchronously with the help of asyncio. I would now like to have the progress bars not taking up the whole width of the app, but have them in an st.columns() next to each other. I am able to put the different progress bars next to each other in a column, but then I’m not able to run them asynchronous. How can I run the progress bars asynchronously inside a column from st.columns()?
Code
import streamlit as st
import asyncio
async def time_passed():
placeholder = st.empty()
t = 0
for i in range(100):
with placeholder.container():
st.markdown("Time passed")
months = abs(t)
days = round((months - int(months)) * 30)
st.metric("Months", f"{int(months)} months {days} days")
t += 3/100
await asyncio.sleep(0.4)
async def trees():
st.markdown("Trees")
st.metric("Months", 2)
progress_text = "Time with trees"
tree_bar = st.progress(0, text=progress_text)
for percent_complete in range(100):
await asyncio.sleep(0.2)
tree_bar.progress(percent_complete + 1, text=progress_text)
async def solar():
st.markdown("Solar")
st.metric("Months", 2.5)
progress_text = "Time with solar"
solar_bar = st.progress(0, text=progress_text)
for percent_complete in range(100):
await asyncio.sleep(0.25)
solar_bar.progress(percent_complete + 1, text=progress_text)
async def hydro():
st.markdown("Hydro")
st.metric("Months", 3)
progress_text = "Time with hydro"
hydro_bar = st.progress(0, text=progress_text)
for percent_complete in range(100):
await asyncio.sleep(0.4)
hydro_bar.progress(percent_complete + 1, text=progress_text)
async def main():
await asyncio.gather(time_passed(), trees(), solar(), hydro())
button = st.button("See time needed per compensation method")
if button:
asyncio.run(main())
Expected behavior:
The progress bars should start asynchronously inside an own column per progress bar.
It is unclear what problem you are having. Where you put the widgets shouldn’t affect how your async code is run and, as far as I can tell, it doesn’t. There is no attempt to use columns in your code. Can you show an example where it doesn’t work as expected?
Sorry if my description was unclear. What I want to do is having for example two or three progress bars next to each other instead on top of each other. That’s why I mentioned st.columns() in order to do this. If there would be another solution to it I’m happy to know. Thanks already for the help.
The async functions are run in main() in the example. So if i put the three async functions in a column (in order to have them displayed next to each other) it does not work as main() is outside of it. What I would need is to somehow put the different async functions that are executed inside main() into different columns, but I can’t find a way to do this. The problem is rather with the layout (having them next to each other) and not with the proper execution of the async code as this works how expected.
You don’t need to put the functions in columns, whatever that means. You can put a widget in a column (or another container) by calling the widget-creation method on the column (col.progress(...)) or using the columns as a context manager (with col: ...).