File Uploader on_change

I’m working on a Streamlit application and part of that application is the user will upload an image, which will then be parsed by GPT.

The UX I’d like to achieve is for the user to upload the image, and if the parsing is successful, have the application automatically populate a series of form fields. Ideally, I’d like for this to happen as soon as the user uploads the file and without requiring that they click on any buttons.

I thought the on_change callback would be the way to do this, so I implemented a process_image function which writes the image to a folder and then sends to GPT. The issue I’m having is that I can’t seem to access the actual byte stream to save the file. So all I’m getting is an empty file.

Is what I’m describing possible? Thanks!

def process_file():
    streamlit_root_logger.debug(f"Uploaded File: {st.session_state['uploaded_invoice']}")
    save_folder = './invoice_images/'
    save_path = Path(save_folder, st.session_state['uploaded_invoice'].name)
    streamlit_root_logger.debug(f"Saved File: {save_path}")
    with open(save_path, mode='wb') as w:
        w.write(st.session_state['uploaded_invoice'].getvalue())

    if save_path.exists() and save_path.is_file():
        st.toast(f"Invoice has been uploaded.")

        # Now analyze the invoice
        st.session_state['parsed_invoice'] = ai_utils.analyze_image(save_path)


with st.container():
    invoice_image = st.file_uploader(label="Upload Invoice",
                                     key='uploaded_invoice',
                                     type=['png', 'jpg', 'jpeg', 'pdf'],
                                     accept_multiple_files=False,
                                     on_change=process_file)

Your code runs fine in my local test. Image is successfully saved in invoice_images folder.

Did you run your app in streamlit community cloud?

@ferdy I don’t know what happened, but I restarted streamlit and it worked. Thanks anyway for your quick response!

1 Like