How do I close the file that Flask's send_file opened, but only after send_file has finished?

52 Views Asked by At

I'm trying to build a Flask app that converts certain files. The workflow includes receiving the original file, saving it to a temporary folder, running my file conversion code, downloading the new file using send_file, and then deleting all the files.

My problem is that send_file opens the new file but doesn't close it, preventing the file from being deleted. This is intentional behavior according to the core developer of Flask:

People misunderstand the fact that send_file opens the file but doesn't close it. Other parts of the WSGI flow will close files after the response is built, so that things like streaming work.

But I can't figure out how to close the file so I can delete it. response.close() will close the file, but will do so before send_file is completed, no matter how much of a delay I try to add inside the cleanup function. It appears that time.sleep() counts down, and then calls send_file while simultaneously closing the file that send_file has opened

@after_this_request
def cleanup(response):
    shutil.rmtree(absolute_folder_name)
    return response

return send_file(path_or_file=flask_output_filepath, mimetype="text/plain", 
                 as_attachment="True", max_age=None)

The .close() method for Flask's response class will close files open in the response object. But it does so before the response completes. Adding a delay with time.sleep() seems to only delay the start of the response, not waiting after the response is made.

I tried pulling

time.sleep(10)
response.close()
shutil.rmtree(absolute_folder_name)

out of the cleanup function and run after calling send_file directly like this:

response = send_file(path_or_file=flask_output_filepath, mimetype="text/plain", 
                     as_attachment="True", max_age=None)
time.sleep(10)
response.close()
shutil.rmtree(absolute_folder_name)
return response

But that didn't help.

0

There are 0 best solutions below