Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Official download component #216

Closed
chriddyp opened this issue Jun 22, 2018 · 9 comments · Fixed by #926
Closed

Official download component #216

chriddyp opened this issue Jun 22, 2018 · 9 comments · Fixed by #926

Comments

@chriddyp
Copy link
Member

There are a few ways that you can download content with Dash:

  1. href URI links: https://community.plot.ly/t/download-raw-data/4700/21
  2. Static URLs with URL parameters: https://community.plot.ly/t/allowing-users-to-download-csv-on-click/5550/12

The former apparently doesn't work in IE11 (plotly/dash-recipes#11) and the latter is a little bit out of the Dash framework (URL parameters instead of just inputs).

So, maybe there is a case for a proper download component.

@chriddyp
Copy link
Member Author

We could possible draw inspiration from here: https://github.com/axetroy/react-download

@amarvin
Copy link

amarvin commented Jun 25, 2018

I've also used Flask functionality for this.

To serve static files:

import os
import dash
from flask import send_from_directory

app = dash.Dash()
STATIC_PATH = os.path.join(app.server.root_path, 'static')
# define layout...
#  add links with, for example: href='/static/test.csv'

@app.server.route('/static/<filename>')
def serve_static(filename):
    return send_from_directory(STATIC_PATH, filename)

Serving dynamic files is also possible with Flask: https://matthewmoisen.com/blog/how-to-download-a-csv-file-in-flask/, which looks similar to URI links, but supports older web browsers

@ieipi
Copy link

ieipi commented Oct 25, 2019

+1 for the feature.

@raghavendrajain
Copy link

Hi. Is it is implemented already now? @chriddyp

@amarvin
Copy link

amarvin commented Nov 29, 2019

Dash has a default static files folder "assets" so any files there can be linked to as "assets/FILENAME.X" so you can use that for e.g. CSS files and downloadable static files. For a downloadable static file just add a link on the page.

Dynamic file downloads still requires an URI link creation.

@raghavendrajain
Copy link

Thannk you @amarvin.

@vcmorini
Copy link

@chriddyp chriddyp removed this from Triage / Discussion Needed in Dash - Stable and Extensive Core Component Libraries Aug 28, 2020
@chriddyp chriddyp added this to Available for Sponsorship in Available for Sponsorship via automation Aug 28, 2020
@chriddyp chriddyp changed the title download component? Official download component Aug 28, 2020
@emilhe
Copy link
Contributor

emilhe commented Sep 10, 2020

I made an unofficial Download component, and i have been considering how it could be merged into Dash. The syntax is currently like this,

import dash
import dash_html_components as html
from dash.dependencies import Output, Input
from dash_extensions import Download

app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download", id="btn"), Download(id="download")])

@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def func(n_clicks):
    return dict(content="Hello world!", filename="hello.txt")

if __name__ == '__main__':
    app.run_server()

Is there any guide to how the syntax should be in Dash? Any comments/ideas?

To enable easy download of common objects such as files or dataframes, i had to add a few utility functions (written in Python). Is there anywhere that these could be put in Dash? Or should they stay in a separate utility library? Here is an example for a dataframe,

import dash
import pandas as pd
import dash_html_components as html

from dash.dependencies import Output, Input
from dash_extensions import Download
from dash_extensions.snippets import send_data_frame

# Example data.
df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [2, 1, 5, 6], 'c': ['x', 'x', 'y', 'y']})
# Create app.
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download", id="btn"), Download(id="download")])

@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def func(n_nlicks):
    return send_data_frame(df.to_excel, "mydf.xls")

if __name__ == '__main__':
    app.run_server()

@alexcjohnson
Copy link
Contributor

I made an unofficial Download component, and i have been considering how it could be merged into Dash.

Great! When you're ready, make a PR to dash_core_components.

Is there any guide to how the syntax should be in Dash? Any comments/ideas?

The above syntax looks good to me, but we would discuss details in the PR review.

i had to add a few utility functions (written in Python). Is there anywhere that these could be put in Dash?

Assuming they're fairly general-purpose (which df-to-excel certainly would be!) these can go in dash_core_components as well, so that they're available to everyone who has the Download component. See https://github.com/plotly/dash-table/blob/dev/dash_table_base/Format.py as an example of how this could work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Available for Sponsorship
  
Available for Sponsorship
Development

Successfully merging a pull request may close this issue.

9 participants