25

Given an iPython notebook running on an external server, is there a way to trigger a file download?

I would like to either be able to have the notebook be able to initiate the download of a file living on the the external server to the where the notebook is being rendered locally, or perform a direct string dump from the notebook workspace into a text file, downloaded locally.

I.E. a powerful and tool would be a Notebook that can query from a database, alter data, and download the query results as a CSV file.

Notebook

A quick experiment showed that a cell containing the following renders a link which downloads a file. I'm hoping for a cleaner solution than rendering data into an html frame.

%%html
<a href="data:application/octet-stream,'string of things'">Download a file</a>
zachd1_618
  • 4,210
  • 6
  • 34
  • 47
  • 1
    You can render a hyperlink with Ipython.display.FileLink. I am sure with some javascript in a markdown cell you can reload the page. – Frames Catherine White Oct 21 '14 at 23:15
  • I saw that, but was unable to render or download the content in the file, found by following the link – zachd1_618 Oct 21 '14 at 23:31
  • You could display some JS calling `window.open(url)` – Thomas K Oct 22 '14 at 01:22
  • 1
    Your idea could be very cool and productivity enhancing. I'd love to see a widget for `ls` that shows the file list, but each file is a hyperlink which when clicked would trigger a download by the web browser. That'd be much faster than switching over to a terminal and doing an `scp`. – NoahR Apr 29 '15 at 15:29
  • 4
    actually, here's a pretty functional solution mentioned in [another StackOverflow question](http://stackoverflow.com/a/24439480/415616) – NoahR Apr 29 '15 at 15:42
  • Any solution using `ipywidgets.Button`? I would like to handle download file I created using `tempfile`. – Darren Christopher Jul 01 '19 at 23:43
  • Does this answer your question? [Retrieving files from remote IPython notebook server?](https://stackoverflow.com/questions/24437661/retrieving-files-from-remote-ipython-notebook-server) – c z Dec 09 '20 at 11:12

4 Answers4

16

I got a working answer from the comments. FileLink did the job, which was to be able to download a file from a notebook.

from IPython.display import display, FileLink

local_file = FileLink('./demo.xlsx', result_html_prefix="Click here to download: ")
display(local_file)

enter image description here

For the sake of completeness, here is a similar example with FileLinks:

from IPython.display import display, FileLinks

local_file = FileLinks('./data/', result_html_prefix="Click here to download: ")
display(local_file)

enter image description here

It's not very pretty, so would love some advice for styling it..

Nick Brady
  • 6,084
  • 1
  • 46
  • 71
  • 1
    What external server does it work on? On Google Colab, the links go to incorrect localhost:8080/filename (instead of Google Colab address/filename). Perhaps there is an extra argument one can pass to FileLinks? – Sint Mar 30 '20 at 09:47
1

Alternatively, if the file's aren't too large and hence suitable for base64 encoding. This only works in 'recent browsers', but ipynb users will likely have one. This example works with JSON data.

from IPython.display import display, HTML
import json
import base64

encoded = base64.b64encode(json.dumps(data).encode('utf-8')).decode('utf-8')
HTML(f'<a href="data:application/json;base64,{encoded}" download="download.json">download</a>')
Herbert
  • 5,279
  • 5
  • 44
  • 69
0

There's a short implementation in the hublib library

https://github.com/hubzero/hublib/blob/master/hublib/ui/download.py

They have several documented examples. (The cb argument is used if you want to customize a callback function.)

https://github.com/hubzero/hublib/blob/master/examples/download.ipynb

MCK
  • 79
  • 1
  • 7
-5

You can use the urllib library to download files or request URLs.

testfile = urllib.URLopener()
testfile.retrieve("http://exmaple.com/file.txt", "file.txt")
charlesreid1
  • 4,360
  • 4
  • 30
  • 52