ipywidgets icon indicating copy to clipboard operation
ipywidgets copied to clipboard

Any way using Upload widget and getting file path in the same time?

Open maihao14 opened this issue 2 years ago • 9 comments

I want to use something similar to the Upload function to select certain files on my local end. The only thing I want to interact with is its file name and file path (because I want to send the file to another function to read the data and do some processes). Just wondering does any ipywidgets could achieve this (without the tkinterk's help)?

maihao14 avatar Apr 26 '22 20:04 maihao14

Here is a toy example that does what you want (the getting the filename and sending it to another function):

import ipywidgets as widgets
from IPython.display import display


main_display = widgets.Output()

def show_it(inputs):
    with main_display:
        main_display.clear_output()
        display(list(inputs['new'].keys())[-1])

upload = widgets.FileUpload(
    accept='.csv',
    multiple=False
)

upload.observe(show_it, names='value')

Screenshot: image

When the Upload button is used to select a file - it passes the filename to the main_display output.

afonit avatar Apr 26 '22 21:04 afonit

Here is a toy example that does what you want (the getting the filename and sending it to another function):

import ipywidgets as widgets
from IPython.display import display


main_display = widgets.Output()

def show_it(inputs):
    with main_display:
        main_display.clear_output()
        display(list(inputs['new'].keys())[-1])

upload = widgets.FileUpload(
    accept='.csv',
    multiple=False
)

upload.observe(show_it, names='value')

Screenshot: image

When the Upload button is used to select a file - it passes the filename to the main_display output.

Thanks for the quick reply. I'm sorry I didn't make it clear. My biggest problem is that how can I get the local file path in the same time? E.g, how can I upload a file then display like Downloads/my_file_folder/text.csv I read some passages saying that because it's a web server so that we cannot get the local directory. Is it possible to achieve this goal? Any suggests are welcome.

maihao14 avatar Apr 26 '22 21:04 maihao14

I don't think that gets exposed - but by virtue of uploading the file with the button its contents are now in memory - so you can pass that data (the contents of the file) to the other functions you want to.

I may be missing your point/utility of knowing the path here.

For example, if I change my show_it function so that it just does:

display(inputs)

You can see the file content in content:

{'name': 'value',
 'old': {},
 'new': {'abc.csv': {'metadata': {'name': 'abc.csv',
    'type': 'text/csv',
    'size': 14,
    'lastModified': 1651008288165},
   'content': b'a,b,c\r\n1,2,3\r\n'}},
 'owner': FileUpload(value={'abc.csv': {'metadata': {'name': 'abc.csv', 'type': 'text/csv', 'size': 14, 'lastModified': 1651008288165}, 'content': b'a,b,c\r\n1,2,3\r\n'}}, accept='.csv', data=[b'a,b,c\r\n1,2,3\r\n'], description='Upload', metadata=[{'name': 'abc.csv', 'type': 'text/csv', 'size': 14, 'lastModified': 1651008288165}]),
 'type': 'change'}

afonit avatar Apr 26 '22 22:04 afonit

Please allow me to re-phrase my question. I want to do some files interaction with deep learning users. Thus, the files could be very big, e.g, a hdf5 file stores the whole dataset. I wanna do something like the upload function because it offers an interface to let the user pick the file he/she wants interactively. But I don't need this function real loading the file, only to fetch the local directory is enough. Currently, I have to use Text() function instead. Because I don't know how to apply FileUpload() to accomplish this. I also attached a demo to illustrate what is the purpose.
image Like the screenshot shows, I want to using an interactive widget to let the user pick the file they need, then print out the file path. In this way, I could using other packages to load and train the data, e.g.,

from EQTransformer.core.trainer import trainer
trainer(path='../ModelsAndSampleData/100samples.hdf5')

maihao14 avatar Apr 26 '22 22:04 maihao14

Ah - thanks for that explanation, that is an interesting use case and I now understand the scenario.

Someone else may be better equipped to answer than me.

However, if I could ask one more question - you said you are using the Text() function currently. Does that mean the files are on the host or the client as they are just typing in the filename?

If they are on the host - why not read the directory where all the data is and offer that as a widget.Dropdown() with the options being the filenames that are on the server then they can just choose from them?

afonit avatar Apr 26 '22 22:04 afonit

Does that mean the files are on the host or the client as they are just typing in the filename?

It depends. Right now, the demo is running in a local Jupyter notebook via Voila. So typing in the filename works fine. However, I'd like to host it on Binder when it's mature. So things would be different. I have no idea if I need to change this way when online. I just starts trying widgets & voila recently, still a pure noob about all these cool things.

If they are on the host - why not read the directory where all the data is and offer that as a widget.Dropdown() with the options being the filenames that are on the server, then they can just choose from them?

Yes, I think this could work, to make a widget.Dropdown() listing all the datasets on the host! However, there might be some user-made local datasets which will need an alternative solution.

I really appreciate your help. And I will make some updates here if I find a better solution for this scenario.

maihao14 avatar Apr 26 '22 23:04 maihao14

@maihao14 I had the same issue as you with ipywidgets and I found ipyfilechooser. Best thing is that it works well with interact_manual too.

Hope that I am not late to the party yet.

Check out more at https://github.com/crahan/ipyfilechooser.

yuenherny avatar Jul 10 '22 15:07 yuenherny

same question

XinyueZ avatar Sep 14 '22 13:09 XinyueZ

Browsing through the documentation of the underlying <input type="file"> HTML element, it doesn't appear possible to get the local file path using the FileUpload widget. @yuenherny pointed out a possible third-party widget that may help, though.

jasongrout avatar Sep 14 '22 13:09 jasongrout