0

I want my server to send a file to the user, and then delete the file.

The problem is that in order to return the file to the user, i am using this:

return send_file(pathAndFilename, as_attachment=True, attachment_filename = requestedFile)

Since this returns, how can i delete the file from the os with os.remove(pathAndFilename)?

I also tried this:

send_file(pathAndFilename, as_attachment=True, attachment_filename = requestedFile)
      os.remove(pathAndFilename)
      return 0

But i got this error:

TypeError: The view function did not return a valid response. The return type must be a string, dict, tuple, Response instance, or WSGI callable, but it was a int.
user1584421
  • 3,499
  • 11
  • 46
  • 86

1 Answers1

1

Since send_file already returns the response from the endpoint, it is no longer possible to execute code afterwards.

However, it is possible to write the file to a stream before the file is deleted and then to send the stream in response.

from flask import send_file
import io, os, shutil

@app.route('/download/<path:filename>')
def download(filename):
    path = os.path.join(
        app.static_folder,
        filename
    )
    cache = io.BytesIO()
    with open(path, 'rb') as fp:
        shutil.copyfileobj(fp, cache)
        cache.flush()
    cache.seek(0)
    os.remove(path)
    return send_file(cache, as_attachment=True, attachment_filename=filename)

In order to achieve better use of the memory for larger files, I think a temporary file is more suitable as a buffer.

from flask import send_file
import os, shutil, tempfile

@app.route('/download/<path:filename>')
def download(filename):
    path = os.path.join(
        app.static_folder,
        filename
    )
    cache = tempfile.NamedTemporaryFile()
    with open(path, 'rb') as fp:
        shutil.copyfileobj(fp, cache)
        cache.flush()
    cache.seek(0)
    os.remove(path)
    return send_file(cache, as_attachment=True, attachment_filename=filename)

I hope your conditions are met.
Have fun implementing your project.

Detlef
  • 6,137
  • 2
  • 6
  • 24