I am running my app locally for now, and seem to be having trouble with the checkbox staying checked.
Working version:
It works well when I use a range of numbers for keys but since I am looping multiple times in my original code, I eventually will hit the duplicate widget ID error.
widget_id = (i for i in range(2))
for i in range(2):
st.checkbox(f"Download latest {i}", key = next(widget_id))
Non working version:
To avoid that, I used a random number generator for the key. Now, the checkbox does not stay checked at all, throwing off the flow of my code.
def infinite_random_number(start:int=0, end:int=10):
while True:
yield random.randint(0,10)
widget_id = infinite_random_number()
for i in range(2):
st.checkbox(f"Download latest {i}", key = next(widget_id))
All this was to avoid duplicate widget id error. I tried generating numbers in a large range but I ran out of unique keys looks like after some runs.
I searched through forums, etc. for solutions but seemed to settle on this which is causing this behavior.
Alternatively, if there is a good solution out there for doing multiple runs and not get duplicate widget id, I am open to that too.
Thanks for the response.
This is my original code snippet.
I am trying to reproduce the problem now with this and am not able to (lot of experiments in the middle might have reset widget id values) but when I keep killing and restarting app multiple times, at some point, I hit the error. I cannot keep streamlit running since it is a shared test machine and I cannot block it for only this. I am thinking, that every restart the key gets assigned a new key and at some point, it hits duplicates. The other part was it seemed to be stuck at the first index for some reason.
#init to avoid out of index range error
input_latest_firmware = [i for i in range(5)]
input_customized_firmware = [i for i in range(5)]
version_filter = [i for i in range(5)]
input_customized_firmware_path = [i for i in range(5)]
firmware_types = ['fw_type1','fw_type2','fw_type3','fw_type4']
widget_id = (i for i in range(10_000))
#customized firmware will provide options to filter by version or a custom path to copy from
for i,type in enumerate(firmware_types, start =0):
input_latest_firmware[i] = st.checkbox(f"Download latest {type} firmware",key = next(widget_id))
input_customized_firmware[i] = st.checkbox(f"Customized {type} firmware", key = next(widget_id))
if input_customized_firmware[i]:
version_filter[i] = st.text_input(f"Requested {type} Version, use format x.x.x.xx: ")
st.write(" OR ")
input_customized_firmware_path[i] = st.text_input(f"Enter local path of {type} firmware hex file: ")
download_ready = st.button("Download", key = next(widget_id))
The other thing I have been thinking of to get around with streamlit to continue to run is having a docker image with streamlit running all the time. The image is launched by user when required. I am relatively new to docker too so not sure if this is a fanciful thinking. I know I am going off on a tangent, but the duplicate widget id issue has been real and ate away a lot of my time, than me spending time on actually working on my app.
And you select “Customized fw_type1 firmware” twice, then duplicated text input widgets will be created. The way you generate the keys is irrelevant, since you are not assigning keys to these widgets.
I see. I do allow the users to pick between latest and customized between runs.
Run1:
fw_type1 could be with latest firmware checkbox and then press download.
Run2:
fw_type1 could be customized firmware checkbox and press download.
But they do have different keys depending on which one, latest or customized, because of the iterator.
Am I understanding this correctly.
I don’t understand what you mean here. I don’t think you can create duplicated widgets this way. I already told you how to trigger the error and why it happens.
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.