While building a mostly widget-based notebook for some other people, I came across a situation where I needed to allow them to export data from a pandas data frame to CSV. This seemed trivial, but it actually was not.
What’s the Problem!?
I was building a notebook that was intended to run on Jupyter Hub… so, not on the same PC as the person using it. So, when I just saved the file, it was on the notebook server and the user could not access it.
Solutions?
My first thought was to have the notebook servers automatically set up a file server and just to save the files there. Then the notebook could give users the URL to the file via the file server. I’m sure this would work, but it requires extra components and would require some clean-up of old files now and then.
While searching online, I found this solution which is much more elegant (though it will take a little extra memory).
It base64 encodes the content and provides a link to it that way (the link actually contains all the data). You can find the original article from medium by clicking here. It has some other options as well. I changed the display line and added an extra import and some altered CSV generation arguments; aside from that it is theirs.
from IPython.display import HTML
import base64
def create_download_link( df, title = "Download CSV file", filename = "data.csv"):
csv = df.to_csv(index=False, line_terminator='\r\n')
b64 = base64.b64encode(csv.encode())
payload = b64.decode()
html = '<a download="{filename}" href="data:text/csv;base64,{payload}" target="_blank">{title}</a>'
html = html.format(payload=payload,title=title,filename=filename)
return HTML(html)
display(create_download_link, your_data_frame)
I hope it helps you!