streamlit / streamlit

Streamlit — A faster way to build and share data apps.
https://streamlit.io
Apache License 2.0
35.67k stars 3.09k forks source link

Add a File Picker Widget #120

Closed treuille closed 4 years ago

treuille commented 5 years ago

Problem

Sometimes it's nice to be able to specify a file on the command line.

Solution

A file picker!

MVP

The file picker can be called as follows:

with st.file_input() as input:
  if input == None:
    st.warning('No file selected.')
  else:
    file_contents = input.read()

Possible additions

Down the line, we could imagine keyword args for filetypes and folder selection.

treuille commented 5 years ago

Requested in the discourse forum.

tvst commented 5 years ago

There are two types of file pickers we should consider: one for files on the machine that is running the Streamlit server, and the other on the machine that is running the brower.

Off the top of my head, a possible API would be something like this:

# Lets you pick files in the machine where "streamlit run" was called,
# but limited to files in "./my_folder/".
# The folder argument is required.
# The type argument is optional.
filename = st.file_picker("Pick a file", folder="my_folder", type=("png", "jpg")) 

# Lets you pick file using the browser's file picker. 
# Maybe even supports drag/drop from your desktop!
# The type argument is optional.
file_bytes = st.file_uploader("Upload a file", type=("png", "jpg"))

What do you think?

treuille commented 5 years ago

I like that API @tvst , although for st.file_uploader I would suggest returning a buffer rather than all the bytes at once.

MarcSkovMadsen commented 5 years ago

I would also need a file uploader for my use case.

User Story: As a user i can upload one or more excel or csv files and see the contents as a table or a chart. If possible I would like to just drag the file onto an area like the https://dash.plot.ly/dash-core-components/upload component.

Congratulations on the very nice product. Streamlit is the columbus egg thats solves

and a lot of other pains.

Very, very well thought work flow. The caching idea is brilliant.

mzeidhassan commented 5 years ago

This will be a great addition to Streamlit. File Picker is essential in data science, so this will be super cool, and it's much needed.

Another User Story:

Upload a text file to process it with a spaCy model for example, then download the results in a text file.

Thanks for the amazing product, and the great documentation. It's super awesome.

dcaminos commented 5 years ago

@tvst looking your comments, you are right. Are two different widgets to create. But, a possible option is create only one widget with both features. Something like this: Screen Shot 2019-10-08 at 12 32 55 PM

Maybe the "Pick from server" button only appears if you wrote a "folder" parameter. My main goal here is to not create several widgets with similar features, that could be confused for user in the future.

treuille commented 5 years ago

@dcaminos 👍 No. I think we should distinguish between these two use case.

My proposal would be to focus on file uploader

input_buffer = st.file_uploader("Upload a file", type=("png", "jpg"))

since the so called file_picker can already be pretty well approximated in Streamlit.

I also second that it would be awesome if we could have a drag-and-drop upload area!

However, before you go ahead @dcaminos , please know that @tvst should be the final decider of what's in scope for this issue.

naurojr commented 5 years ago

The solution on google colab is very easy to use I think.

from google.colab import files
uploaded = files.upload()
intake_sheet = ""

for fn in uploaded.keys():
       intake_sheet = fn

df_intake = pd.read_excel(intake_sheet)

It uploads the file to the server as a temporary asset. Once I have it in Pandas I can delete the file, or Colab will do that automatically at the end of the session.

Something like what @tvst is suggesting would be even better.

ajinkya933 commented 5 years ago

any update on this ? It is the only thing stopping me from productionising my model using streamlit. Any help is greatly appreciated.

RNogales94 commented 5 years ago

@tvst

I think your second option (upload using the browser) give final users the option to process their own data using the application. I'm thinking in provide a web tool made by the machine learning team which can allow quality department to validate data and manually tag data.

They can upload a untagged csv file and visualize the data sample by sample in a webtool for tag and see the recommended tag (kind off reinforcement learning but for supervised models)

isConic commented 5 years ago

This may be much, but I like drag and drop interfaces. Click to upload, or drag and drop. For my specific use case, people may be dragging images to create facial biometrics.

Edit:
I did some very basic digging around. Found this drag-and-drop interface for uploads.
https://www.dropzonejs.com/#new-video-out-now

image

image

From a glance, their demo is up to the design standards I've seen in streamlit.

tvst commented 5 years ago

any update on this ?

We're working on this right now. My guess is it will be released in a couple of weeks, but don't hold me to it :wink:

This may be much, but I like drag and drop interfaces.

You're in luck! We use Base Web for our widgets and their file uploader works exactly how you propose: https://baseweb.design/components/file-uploader/

MarcSkovMadsen commented 5 years ago

Hi @tvst.

Does that mean that all the components at https://baseweb.design/ would be something that could be supported in Streamlit when you have the time/ resources to develop the integration with Streamlit?

And that right now the easiest request whenever we lack some component is really saying we need component X from that site?

rohts-patil commented 5 years ago

Thanks for the great work guys. When will be this available?

imneonizer commented 5 years ago

Just look the behaviour of your modern website upload files it could be from url or local system. For the api i would appreciate sticking to Python base code, something like

image = st.upload() #parameter can be mode="r", buffer="1mb”, load_in_memory=True

If a path is a added, streamlit will automatically load that file into memory otherwise if a file is dropped over the widget it will directly load it into memory and after that its user choice to save it on to the server or anywhere.

treuille commented 5 years ago

I think it's important that the file not be saved immediately to the server filesystem. I think it should either:

  1. return a bytes object
  2. return a file object (which, for example, would turn into byes with .read() -- preferred!)
g0lemXIV commented 5 years ago

Easy way to upload files now is use tkinter like


import tkinter as tk  
from tkinter import filedialog  
if st.button('Upload file'):  
    root = tk.Tk()  
    root.withdraw()  
    file_path = filedialog.askopenfilename()  
    st.image(file_path)``` 
ajinkya933 commented 5 years ago

@g0lemXIV I get this error on MAC OS terminal when I ran your code and pressed the upload file button:

2019-11-03 21:05:24.521 python[843:13407] WARNING: NSWindow drag regions should only be invalidated on the Main Thread! This will throw an exception in the future. Called from (
    0   AppKit                              0x00007fff331bf7f0 -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled] + 371
    1   AppKit                              0x00007fff331bcce1 -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1416
    2   AppKit                              0x00007fff33268fa4 -[NSPanel _initContent:styleMask:backing:defer:contentView:] + 50
    3   AppKit                              0x00007fff331bc753 -[NSWindow initWithContentRect:styleMask:backing:defer:] + 42
    4   AppKit                              0x00007fff33268f59 -[NSPanel initWithContentRect:styleMask:backing:defer:] + 64
    5   AppKit                              0x00007fff33b5261e -[NSSavePanel initWithContentRect:styleMask:backing:defer:] + 97
    6   AppKit                              0x00007fff33b5a828 -[NSOpenPanel initWithContentRect:styleMask:backing:defer:] + 151
    7   AppKit                              0x00007fff3345519a -[NSPanel init] + 75
    8   AppKit                              0x00007fff33b525b6 -[NSSavePanel init] + 80
    9   AppKit                              0x00007fff33843ef5 +[NSSavePanel(Instantiation) _crunchyRawUnbonedPanel] + 81
    10  libtk8.6.dylib                      0x000000011fdfc6b0 Tk_GetOpenFileObjCmd + 80
    11  libtcl8.6.dylib                     0x000000011fbb1b26 Tcl_EvalObjv + 342
    12  _tkinter.cpython-37m-darwin.so      0x000000011fb84572 Tkapp_Call + 210
    13  python                              0x0000000103f13c9e PyCFunction_Call + 174
    14  python                              0x000000010404db9d _PyEval_EvalFrameDefault + 46621
    15  python                              0x000000010404134a _PyEval_EvalCodeWithName + 410
    16  python                              0x0000000103f13313 _PyFunction_FastCallKeywords + 195
    17  python                              0x000000010404fc67 call_function + 183
    18  python                              0x000000010404c9ed _PyEval_EvalFrameDefault + 42093
    19  python                              0x000000010404134a _PyEval_EvalCodeWithName + 410
    20  python                              0x0000000103f13313 _PyFunction_FastCallKeywords + 195
    21  python                              0x000000010404fc67 call_function + 183
    22  python                              0x000000010404ca83 _PyEval_EvalFrameDefault + 42243
    23  python                              0x000000010404134a _PyEval_EvalCodeWithName + 410
    24  python                              0x000000010403bd7b builtin_exec + 347
    25  python                              0x0000000103f13446 _PyMethodDef_RawFastCallKeywords + 230
    26  python                              0x000000010404fce2 call_function + 306
    27  python                              0x000000010404d9c5 _PyEval_EvalFrameDefault + 46149
    28  python                              0x0000000103f12be5 function_code_fastcall + 117
    29  python                              0x000000010404fc67 call_function + 183
    30  python                              0x000000010404c9ed _PyEval_EvalFrameDefault + 42093
    31  python                              0x0000000103f12be5 function_code_fastcall + 117
    32  python                              0x0000000103f16002 method_call + 130
    33  python                              0x0000000103f13a82 PyObject_Call + 130
    34  python                              0x000000010404dbf2 _PyEval_EvalFrameDefault + 46706
    35  python                              0x0000000103f12be5 function_code_fastcall + 117
    36  python                              0x000000010404fc67 call_function + 183
    37  python                              0x000000010404c9ed _PyEval_EvalFrameDefault + 42093
    38  python                              0x0000000103f12be5 function_code_fastcall + 117
    39  python                              0x000000010404fc67 call_function + 183
    40  python                              0x000000010404c9ed _PyEval_EvalFrameDefault + 42093
    41  python                              0x0000000103f12be5 function_code_fastcall + 117
    42  python                              0x0000000103f16002 method_call + 130
    43  python                              0x0000000103f13a82 PyObject_Call + 130
    44  python                              0x000000010413189b t_bootstrap + 123
    45  python                              0x00000001040b8937 pythread_wrapper + 39
    46  libsystem_pthread.dylib             0x00007fff6d434d76 _pthread_start + 125
    47  libsystem_pthread.dylib             0x00007fff6d4315d7 thread_start + 15
)
mkinet commented 5 years ago

+1 for this feature, we definitely need it in our projects! @tvst any idea when it will be available?

Thanks for the awesome work !

sssdjj commented 5 years ago

I need upload

sssdjj commented 5 years ago

Problem

Sometimes it's nice to be able to specify a file on the command line.

Solution

A file picker!

MVP

The file picker can be called as follows:

with st.file_input() as input:
  if input == None:
    st.warning('No file selected.')
  else:
    file_contents = input.read()

Possible additions

Down the line, we could imagine keyword args for filetypes and folder selection.

do you have this function?

isConic commented 5 years ago

@sssdjj
This function is not there yet.

There is possibly a functional pull request for this feature that is being worked out right now.

Check it out: https://github.com/streamlit/streamlit/pull/488

carlthome commented 4 years ago

I'm sure there are many security concerns with this feature and that it's non-trivial to implement but this is the main thing I'm missing from the otherwise wonderful workflow that has been streamlit thus far.

My hope is to use streamlit to demo deep learning models, in which the input is typically an image, audio or video file. Copy+pasting a base64 string into a text input isn't sufficiently user friendly for my target users.

asghar3166 commented 4 years ago

Uploading [text, csv] file feature is needed. Any solution, please share. Appreciate in advance

universewill commented 4 years ago

Any update here? Really need a file uploader func

sssdjj commented 4 years ago

0.51.0 have upload?

isConic commented 4 years ago

@dcaminos I see that you've closed this. Has this feature been merged? Or was it de-prioritized?

jrhone commented 4 years ago

@isConic merged via https://github.com/streamlit/streamlit/pull/488

treuille commented 4 years ago

@sssdjj and @isConic : The file picker was released in Streamlit 0.52. Happy new year! 🎆

pietz commented 4 years ago

Wow, this turned out pretty great. Thanks for everyone who worked on this!

Screenshot 2020-01-06 at 09 26 39

Minimal example:

uploaded_file = st.file_uploader("Choose a file", type=['txt', 'jpg'])
if uploaded_file is not None:
    # do stuff
samuelefiorini commented 4 years ago

Hi, thanks for the great work! Is it also possible to select a folder in a similar way?

armstrys commented 4 years ago

I would appreciate being able to select a folder too if possible. Right now it seems that dropping a folder into the widget selects the contents of the folder. Would be great if it could instead return a path!

simon-bt commented 4 years ago

is it possible to increase the max file size?

karthickrajas commented 4 years ago

is it possible to increase the max file size?

By default, uploaded files are limited to 50MB but you can configure that using the server.maxUploadSize config option.

karthickrajas commented 4 years ago

Hi,

Thanks for the amazing feature. really great.! I just have one doubt, instead of loading the file, can i just get the filename with the filepath alone?

Regards, Karthick

bvandijkman commented 4 years ago

I would appreciate being able to select a folder too if possible. Right now it seems that dropping a folder into the widget selects the contents of the folder. Would be great if it could instead return a path!

This would be great for me as well, as I want to run a script over all the files that are placed in a folder chosen by the user.

vbucaj commented 4 years ago

This is awesome! I've spent an embarrassing number of hours trying to figure out a way to upload files from my local computer onto the deployed app! I'm glad I ran into this! It's exactly what I needed, and now my app works as intended! :)

H4dr1en commented 4 years ago

Very nice feature! Is it possible to retrieve the path of the file, instead of the file itself?

tonymonk007 commented 4 years ago

Very nice feature! Is it possible to retrieve the path of the file, instead of the file itself?

Would be very useful to get the file path.

60nocolus commented 4 years ago

Amazing job you guys! My project is finaly coming around with streamlit! You have absolutely changed the game!!!

inavamsi commented 3 years ago

Thanks guys. Amazing work!

benlansdell commented 2 years ago

For those looking for a file picker, not a file uploader, I have made the following not-too-janky solution:

https://gist.github.com/benlansdell/44000c264d1b373c77497c0ea73f0ef2

This lets you navigate directories to select a file/directory on the server Streamlit is running on.

Kapture 2022-09-15 at 14 35 05

This is perfectly functional for my case.

goyalyashpal commented 1 year ago

I want to run a script over all the files that are placed in a folder chosen by the user.

exactly, my task also requires executing statements based on folder and the files it contains within.

think for example: like having multiple contacts - each contact as a folder, and each contact stores its own pic, details etc as files in that folder.

tgscan-dev commented 1 year ago

@sssdjj and @isConic : The file picker was released in Streamlit 0.52. Happy new year! 🎆

where?

rosmur commented 8 months ago

The feature that was shipped in Streamlit 0.52 is a file uploader, not a file picker right?

Im looking for a very simple feature where a user can pick a file using the OS default dialog box and the function returns the path to the file picked. (The intent is to then pass that file path to pandas to read)