question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

file_uploader does not repopulate the UploadedFile stream when the app is rerun

See original GitHub issue

Summary

I use st.file_uploader to allow the user to submit their own data. Then I do an action based on this data and other user-provided parameters (coming from an st.slider for instance). Re-running the app produces an error. This includes when the parameters are changed (for example by moving the st.slider). After investigating, I discovered that it is because, after the first reading of the UploadedFile output by st.file_uploader, the UploadedFile stays empty. It is not re-populated by the uploaded file in spite of the app re-running.

Steps to reproduce

  1. Save the following JSON as “test.json”:
{"a": 3, "b": 2}
  1. Save the following piece of code as “my_app.py” (or any other name):
import json
import streamlit as st

st.title("Let's add a number to the elements of a json")

uploaded_file = st.sidebar.file_uploader(
    "Upload your json", type=["json"]
)

to_add = st.sidebar.slider(
    "Choose a number", min_value=1, max_value=5, value=3
)

st.markdown("The result is:")

default_file = open("test.json", "r")
if uploaded_file is None:
    dico = json.load(default_file)
else:
    dico = json.load(uploaded_file)
st.write({k: v + to_add for k, v in dico.items()})

default_file.close()
  1. Run streamlit run my_app.py
  2. In the app, upload test.json in the file uploader. You should see that: Capture d’écran 2020-10-16 à 01 28 35
  3. Move the slider, here is the bug, you should see that: Capture d’écran 2020-10-16 à 01 28 41
  4. At this point, re-uploading works, but the user shouldn’t have to re-upload the file after each slider change or each plain re-run. Especially since, as we see in the screenshot above, the widget still displays the informations of the uploaded file. Here is how it looks after re-uploading: Capture d’écran 2020-10-16 à 01 32 20

Expected behavior:

We shouldn’t ever get to the second screenshot. We should pass from the first to the third simply by moving the slider and without re-uploading the file every time.

Actual behavior:

As explained above, after the first run the stream is empty and not reset when the app is re-run. This is not specific to the JSON format, although the error message displayed above is. I have run the same test with a CSV file and pandas.read_csv. The underlying cause is the same: an empty stream.

Note that I have also tried to make an auxiliary function that encapsulates the dico = json.load(uploaded_file) part and which is decorated by st.cache. It still doesn’t work.

Is this a regression?

I don’t know, it’s the first time I use st.file_uploader.

Debug info

I have two different settings.

An AWS distant machine (I forward the port to my local machine):

  • Streamlit version: 0.69.1
  • Python version: 3.7.6
  • Using Conda
  • OS version: I don’t know

My local machine:

  • Streamlit version: 0.68.0
  • Python version: 3.8.5
  • Not using Conda
  • OS version: macOS 10.13.6
  • Browser version: Firefox 81.0.1

Additional information

Side note on the documentation of st.file_uploader: at the some point it says to use StringIO(uploaded_file.decode("utf-8")) but this doesn’t work and raises AttributeError: 'UploadedFile' object has no attribute 'decode'. Using StringIO(uploaded_file.read().decode("utf-8")) does work, though.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
FrankKrcommented, Oct 28, 2020

Exalate commented: FrankKr commented: Update: Actually, it appears the UploadedFile stream is available, but the cursor is at the end of the stream after the first evaluation. A work-around for me was to reset the cursor by including uploaded_file.seek(0) after the check if uploaded_file is None. Would very much prefer this workaround to become obsolete.

in your example:

default_file = open("test.json", "r")
if uploaded_file is None:
    uploaded_file.seek(0)
    dico = json.load(default_file)
else:
    dico = json.load(uploaded_file)

st.write({k: v + to_add for k, v in dico.items()})

default_file.close()

original: experiencing the same issue after upgrading streamlit from version 0.64.0 to 0.69.0

0reactions
karriebearcommented, Oct 29, 2020

Closing this issue as a duplicate of #2235. A fix for this should be coming in the next release. Please track #2235 for updates.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring MVC File Upload Help - java - Stack Overflow
This is what i prefer while making uploads.I think letting spring to handle file saving, is the best way. Spring does it with...
Read more >
st.file_uploader - Streamlit Docs
If no files were uploaded, returns an empty list. The UploadedFile class is a subclass of BytesIO, and therefore it is "file-like". This...
Read more >
10 useful HTML file upload tips for web developers
1. Simple file upload. We can specify the input type as file to use the file uploader functionality in a web application.
Read more >
Need to upload a video file? - Resi Documentation
View the status of uploaded file. Here is a list of possible statuses of your video file. View Encoder Event from your video...
Read more >
How to build a file upload service with vanilla JavaScript
Divide and stream the file in chunks to the backend · // file content · const · // fix chunk size · const...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found