When more than one widget is made with the same key, there is a duplicate widget id error, and this is expected. However, when a placeholder is made and updated with the same widget twice, the error is still raised, despite there technically only being one widget. Here is the example:
import streamlit as st
import time
placeholder = st.empty()
while True:
placeholder.text_area("Hi", key="placeholder")
time.sleep(5)
I tried amending this by deleting from the cache but the same thing happens:
import streamlit as st
import time
placeholder = st.empty()
while True:
if "placeholder" in st.session_state:
del st.session_state["placeholder"]
placeholder.text_area("Hi", key="placeholder")
time.sleep(5)
This is the pattern that I use in a dashboard I’m making, and it’s important that I set a key, because I want to get the value in a callback function and I don’t believe there is another way to pass a widget’s value into its callback. I want to use a callback to leverage the “on change” nature of it, rather than detect a change with the returned string of a text_area, although that may be the only way I can work around this.
I am afraid the widget state persists in some way until the script is run again and that’s why you can’t instantiate another one with the same key.
You might use a UUID as the key but if I am right then that would be a memory leak, so don’t do it unless you can ensure the number of iterations has an upper bound.
placeholder.text_area("Hi", key=uuid.uuid4())
OTOH do you really need a loop and replacing the widget? This code seems to achieve the same.
The loop fetches data from databases, would I be able to update my dashboard in your suggestion?
Edit: logically, it seems like I would be able to. Wouldn’t this be reloading all my other UI though?
I also just thought of assigning a random key and passing that in the callback, but I might not have an upper bound and did not consider the memory usage
Didn’t try any code myself, however just a long shot regarding the memory leak: Did you try to garabage collect in between script runs? Maybe a simple gc.collect() will help?
Other than that, I believe currently the only solution is to st.experimental_rerun(). Unfortunatelly, there is currently no way to only update a single widget.
I don’t see why my suggestion of rerun the app instead of having a loop would not work for you. Reloading the UI should not be a problem, that is how streamlit is designed to work.
That is a problem when you have elements that take a long time to render, like complex charts with lots of data. But replacing widgets forever willl leak unbounded amounts of memory.
Maybe a mixed approach, where a rerun is triggered every now and then to free memory would work. Or being creative with the dashboard design: simpler widgets are faster to render and there can be different views so that not everything needs to be on sight at the same time.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.