Skip to content
Advertisement

How to download a file with plotly-dash on a multi-page app?

I already know about the following approach (link here):

server = Flask(__name__)
app = dash.Dash(server=server)


@server.route("/download/<path:path>")
def download(path):
    """Serve a file from the upload directory."""
    return send_from_directory(UPLOAD_DIRECTORY, path, as_attachment=True)

But the problem is, when I use a multi-page-approach like suggested from Plotly (link here (below “Structuring a Multi-Page App” – index.py)):

    app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content')
])


@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/apps/app1':
        return app1.layout
    elif pathname == '/apps/app2':
        return app2.layout
    else:
        return '404'

I cannot use server.route because it will be caught by the callback shown above.

What is the best way to still make files downloadable?

Advertisement

Answer

Ok, I have solved it now.

In the documentation it says:

The dcc.Location component represents the location or address bar in your web browser.

So I used an html.A element with the download option. As stated here, download

Prompts the user to save the linked URL instead of navigating to it.

This means when the user clicks on the link, it doesn’t change the address bar. Hence, the callback from the display_page(pathname) isn’t called and the link is directed to the download(path)-method via the @server.route statement.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement