Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run code after Flask send_file() or send_from_directory()

I have a Flask-based website where users can download some PDF files.

This is straightforward to implement using Flask's send_file() and send_from_directory().

For example:

@app.route('/downloadreport')
def download_report():
    return send_from_directory(
        '/reports', 
        'my_report.pdf', 
        as_attachment=True)

I'd like to perform some logic (let's call it after_download()) AFTER the download is complete.

I've tried using the @after_this_request hook. But it looks like send_file() runs asynchronously so @after_this_request may fire before the file is downloaded.

  • For example, if the file is very large, a download may take a while so @after_this_request seems to fire while the file is being downloaded.
  • It looks from the documentation like send_file() uses WSGI's file wrapper to effectuate the download...maybe that's why it's running asynchronously?

Is there a way to call after_download() so that it's guaranteed to run after send_file() has completed sending the file to a user?

like image 657
tohster Avatar asked Mar 22 '15 07:03

tohster


1 Answers

You can't. While send_file streams the file using Flask when using the dev server, it may (and really should for performance) use the web server (nginx, apache, etc.) and X-SendFile in production. Since the web server is beyond the control of the application, you're out of luck.

like image 166
davidism Avatar answered Oct 22 '22 08:10

davidism