New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🎬 : Improved file uploader and camera input to call its on_change handler only when necessary #4270
Conversation
…loadedFile instances with same FileRec. We need that change to prevent `on_change` call for file_uploader on rerun.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM, but I think we'll also want to check in with core platform to verify that doing this won't have any unintended consequences
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems fine to me and I don't think it interferes with anything we're doing over here -
BUT, it'd be ideal if it had a test to prevent against regressions of the bug it's addressing. (Just something that asserts that the fileuploader callback isn't called when the file hasn't changed.)
def __eq__(self, other): | ||
if other is not None: | ||
return self.id == other.id | ||
return False | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be really correct, __eq__
should typecheck its argument (and we might as well also type-annotate the function)
def __eq__(self, other: object) -> bool:
if not isinstance(other, UploadedFile):
return NotImplemented
return self.id == other.id
(This StackOverflow has more details about the weird "return NotImplemented" line: https://stackoverflow.com/questions/878943/why-return-notimplemented-instead-of-raising-notimplementederror)
Hi, maybe it's not the place but i am using streamlit 1.27 and I have checked for 1.28 and 1.29 too that "on change" function is executing every time the app is reloaded. Here snippet of my app: import streamlit as st
def session_state_counter():
if "counter" in st.session_state:
st.session_state.counter = st.session_state.counter + 1
else:
st.session_state.counter = 1
file_raw = st.file_uploader(
"Upload_file",
on_change=session_state_counter(), # on change does not work
)
st.button("Click me to test counter :)")
st.write(f"Counter: {st.session_state.counter}") |
We need that change to prevent
on_change
call for file_uploader on rerun.📚 Context
Fix for #4256 .
When file uploaded to file_uploader, each rerun triggers
on_change
callback call.This happens because we in
session_state.py
we check is old and new values are the same.But since
st.file_uploader
returns a newUploadedFile
object each time in deserialize method values are not equal.I override
__eq__
method forUploadedFile
to check equality via underlyingUploadedFileRecs
idsWhat kind of change does this PR introduce?
🧠 Description of Changes
Add bullet points summarizing your changes here
Revised:
Insert screenshot of your updated UI/code here
Current:
Insert screenshot of existing UI/code here
🧪 Testing Done
🌐 References
Does this depend on other work, documents, or tickets?
Contribution License Agreement
By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.