Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
380 views
in Technique[技术] by (71.8m points)

python - How to clean up temporary file used with send_file?

I'm currently developing a server side json interface where several temporary files are manipulating during requests.

My current solution for cleaning up these files at the end of the request looks like this:

@app.route("/method",methods=['POST'])
def api_entry():
    with ObjectThatCreatesTemporaryFiles() as object:
        object.createTemporaryFiles()
        return "blabalbal"

In this case, the cleanup takes lace in object.__exit__()

However in a few cases I need to return a temporary files to the client, in which case the code looks like this:

@app.route("/method",methods=['POST'])
def api_entry():
    with ObjectThatCreatesTemporaryFiles() as object:
        object.createTemporaryFiles()
        return send_file(object.somePath)

This currently does not work, because when I the cleanup takes place flask is in the process of reading the file and sending it to the client. ¨ How can I solve this?

Edit: I Forgot to mention that the files are located in temporary directories.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The method I've used is to use weak-references to delete the file once the response has been completed.

import shutil
import tempfile
import weakref

class FileRemover(object):
    def __init__(self):
        self.weak_references = dict()  # weak_ref -> filepath to remove

    def cleanup_once_done(self, response, filepath):
        wr = weakref.ref(response, self._do_cleanup)
        self.weak_references[wr] = filepath

    def _do_cleanup(self, wr):
        filepath = self.weak_references[wr]
        print('Deleting %s' % filepath)
        shutil.rmtree(filepath, ignore_errors=True)

file_remover = FileRemover()

And in the flask call I had:

@app.route('/method')
def get_some_data_as_a_file():
    tempdir = tempfile.mkdtemp()
    filepath = make_the_data(dir_to_put_file_in=tempdir)
    resp = send_file(filepath)
    file_remover.cleanup_once_done(resp, tempdir)
    return resp

This is quite general and as an approach has worked across three different python web frameworks that I've used.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...