user10058776
user10058776

Reputation: 183

Downloading a file in downloads directory - flask, python

I have a flask app in which it has a button to download an HTML report. The download button when hit creates an xlsx file. It worked fine until that app was running on my local server because the python code found my Downloads directory no matter what os it is using python's os module.

Now the app is deployed on a remote server, in this case, how do you let the system know the client's download directory path where this xlsx file can then be created? Or any other pointers for a better solution if I'm missing something?

Upvotes: 0

Views: 3156

Answers (2)

quqa123
quqa123

Reputation: 675

If i understand correctly - you want to specify a directory to which the file should be downloaded on users computer when he/she hits download button.

This is not possible, and is handled fully by the browser.

Browser processes the request/stream of special type and then creates the output file in the location specified by the user in browser settings. The os library which you mentioned relates to your server machine not client, so any os opertaions that you provide in your code will be executed on your server (like creating a file). So that's why it worked on your local machine - which was server and client at once.

Why is it disallowed?

Imagine a "virus file" being uploaded to your C:\Windows\System32. Web applications could be granted control over your machine with a simple button download. The huge security issue doesnt allow for client's machine access from web application

Upvotes: 2

damon
damon

Reputation: 15128

To serve a user a file to download, the webserver needs to deliver it in a special way. You can't use the os module to write to the user's computer. It worked locally, because your server was the same computer as your user environment in the browser.

The correct way to serve a user a file for downloading is to use flask's send_file method.

To show you the process, I've created an example below. In this example, I'm assuming that you have a function called build_report(...) which accepts a report_id and returns an io.BytesIO object containing the content of the xlsx file.

from flask import send_file

@app.route("/download-report/<report_id>")
def download_report(report_id):
    file_obj = build_report(report_id)
    return send_file(
        file_obj,
        mimetype="application/vnd.ms-excel",
        attachment_filename=f"report-{report_id}.xlsx",
    )

Upvotes: 1

Related Questions