Eel: getting file path

Created on 4 Dec 2018  路  6Comments  路  Source: ChrisKnott/Eel

Hello, i have an input of type file, i want to get the path from the input to my python script, for example electron provides an additional input.files[0].path field that allows for this to happen, since the default web browser path would look like this c:/fakepath/filename.

Most helpful comment

For security reasons it is not possible to get the file path through the browser as @ChrisKnott said. Using the Tkinter library, you can easily do it as shown in the example below.

app.py

@eel.expose
def btn_ResimyoluClick():
    root = Tk()
    root.withdraw()
    root.wm_attributes('-topmost', 1)
    folder = filedialog.askdirectory()
    return folder

main.html

<script>
async function getFolder() {
var dosya_path = await eel.btn_ResimyoluClick()();
    if (dosya_path) {
        console.log(dosya_path);
    }
}
</script>
<a onclick="getFolder()">GetFolder</a>

All 6 comments

I don't think it's possible. The workaround I personally picked is to use the tkinter to do that (https://pythonspot.com/tk-file-dialogs/) . As this is in the standard library, this is not a problematic dependency to manage.

I did the same as @brumar. It's not possible unless you actually do use Electron as the browser

For security reasons it is not possible to get the file path through the browser as @ChrisKnott said. Using the Tkinter library, you can easily do it as shown in the example below.

app.py

@eel.expose
def btn_ResimyoluClick():
    root = Tk()
    root.withdraw()
    root.wm_attributes('-topmost', 1)
    folder = filedialog.askdirectory()
    return folder

main.html

<script>
async function getFolder() {
var dosya_path = await eel.btn_ResimyoluClick()();
    if (dosya_path) {
        console.log(dosya_path);
    }
}
</script>
<a onclick="getFolder()">GetFolder</a>

I don't know if it's useful for anyone, but a creative alternative could be to use a jquery plug-in (like this one) to give the user an in-browser experience of file choosing. You need to make it call the python back-end so that it informs the plugin of the files and directory name at a given path (by using both os.listdir(path) and os.path.isdir(filepath). It's not the easiest path, but depending on you use case, that may fit.

Edit : I just tried it, the integration was quite straightforward. In case some people are interested :

backend.py

from pathlib import Path
HOME = str(Path.home())
@eel.expose
def get_root():
    return HOME

@eel.expose
def get_path_infos(path):
    try:
        files = os.listdir(path)
        real_files = [f for f in files if os.path.isfile(os.path.join(path, f))]
        real_dirs = [f for f in files if os.path.isdir(os.path.join(path, f))]
    except PermissionError:
        eel.alert_error("Can't read this files")
        return {"dirs": [], "files": []}
    except Exception as e:
        #do some things
        return {"dirs": [], "files": []}
    return {"dirs": real_dirs, "files": real_files}

script.js (adapted from https://github.com/jcubic/jquery.filebrowser)

$(function() {
    asynccontext = async function(){
        rootpath = await eel.get_root()()
        var browse = $('#browser').browse({
            root: rootpath,
            separator: '/',
            contextmenu: true,
            dir: function(path) {
                return(eel.get_path_infos(path)());
            },
            open: function(filename) {
                console.log('opening ' + filename);
            }
        });
    };
    asynccontext();
});

Of course you have to download the js, css, svg files from the repository and set up an index.html a bit like this.
```html









edit: correct errors in code

thank you everyone for the amazing responses, i have been using this, i just thought i would open an issue for this to be added.

I ran into this issue as well. Was hoping for some sort of solution like Electron as the OP mentioned. However, I understand why it doesn't exist. I wasn't a fan of the solutions given because you have to modify the UI and having a web frontend UI is the whole reason for the Eel library.

From the JS side we have the filename, last modified date, and file size in bytes. You can search filesystem on Python side for name match and weed out duplicates based on modified date & file size. Alternatively, you can calculate a checksum hash from the base64 file data on JS side and use that for searching on Python side. I'll implement this and post here for those interested. I can't imagine the run time is going to be great.

Edit: I implemented this two ways:

  1. When the file is selected on HTML side, call readAsArrayBuffer and send the byte array as a variable to python via eel exposed function that is then saved to a temporary file and therefore you know the path. Downsides: redundant data. Takes a LONG time for the data to be passed to Python even for files < 1MB.
  2. The solution I thought of above, doing a file search on Python side. It's also way too slow, even on my SSD and using heuristics for search locations.

I'll try setting electron as the client-side browser and maybe I can get access to the file path field it attaches as @ChrisKnott
suggested and report back.

Edit 2: following #57 and the Electron-Eel minimal example I was able to get Electron up and running as my client with Eel. All <input type="file"> now have a path variable attached to them with the absolute path. A little bit of setup but works great and no hacky solutions necessary. This is the way to go 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

abdurahman-shiine picture abdurahman-shiine  路  3Comments

ghost picture ghost  路  6Comments

andrewtquick picture andrewtquick  路  4Comments

datainvestor picture datainvestor  路  5Comments

sameera-madushan picture sameera-madushan  路  3Comments