Local download without showSaveFilePicker() possible?

The only examples I found for saving files locally from PyScript are using file picker (1, 2).

Is it - by any chance - possible to save a file from PyScript to your local device without using file picker?

I was thinking of some kind of JS callback function when I save something to the virtual file system.

Let’s consider a simple pandas df:

d = {'col1': [1, 2], 'col2': [3, 4]}
df = pd.DataFrame(data=d)

If I call df.to_excel("test.xlsx") it saves it to the virtual file system. How could I trigger the automatic local download here?

2 Likes

Hi @Dome - the key thing to recall is it’s operating inside the browser’s sandbox.

I’m not an expert on file downloads from browsers but without a file picker how will anything inside be able to know of and/or access a file location outside the sandbox?

Depending on your browser, you may be able to tell it to save any downloads to a default location but that’s a browser specific thing and happens without what’s inside the browser being aware.

Using the File System Access API, The File System Access API: simplifying access to local files may allow a little more advanced handling but i think it’s still somewhat restrictive and it’s not something I’ve got enough experience to comment on.

EDIT: I’ve just seen the examples you linked to do actually use the File System Access API

1 Like

Hi @neil!
Thanks for your input. The main reason why I don’t like the file picker solution (yet) is that it’s not (yet) cross-platform and e.g. not working for Firefox (see your link). Also, binary files make everything a lot more complicated.

As far as I understand there are certain callbacks available you can trigger right in the python code.
So let’s say you run your code, buffer the df as a simple JS array in a global variable and trigger some custom JS download function, e.g. with some third party libraries handling the more sophisticated blob operations.

Else, I have a hack in mind (I’d prefer rather not to use):

  • “buffer” my df in the DOM as e.g. the value of a hidden input field or similar (e.g. csv format)
  • add some kind of on_change listener in JS (might be hacky to make this work however as it’s not user input)
  • trigger the above mentioned JS (native) function reading the input value with a third party library and converting csv to any binary format like xlsx

But that’s quite hacky and I really don’t like all the back and forth conversion of non-binary to binary.

I already opened an issue on GitHub as I see the need for better documentation on file handling in general.

If you find any other good examples (or hacks) let me know!

2 Likes

There are several APIs that you can use. Those are the same APIs that JavaScript applications use. However, all APIs require a user gesture, such as clicking a button, to initiate a file save. No browser-based applications can write to the local file system themselves. The browser performs the actual write operation.

1 Like

Do you have any hint for a convenient cross-browser API or any examples?
The user action is fine for my use case but I’d like it to work on all devices.