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.