rID133
rID133

Reputation: 163

NamedTemporaryFile() for clearing files after flask send_file

I am using a flask server to return a processed image file after a request. I'm using google cloud run and from my understanding of the concurrency, I should be deleting files as I go to reduce memory usage of the instances that are spun up. For this purpose I've chosen to use NamedTemporaryFile() in a 'with' statement - my understanding is that the default behaviour is that once you exit the 'with' statement the temp file gets deleted.

This is the code I have to return the processed image.

   @app.route('/')   
   def hello():
      "image processing"
      with NamedTemporaryFile() as temp:
        cv2.imwrite(str(temp.name),img_processed) 
        return send_file(str(temp.name), mimetype='image/png')

However, since I am trying to return the function in the 'with' statement, will the temp file still be deleted? Also am I using NamedTemporaryFile() correctly? The examples I've seen use temp.write but since I am using cv2.imwrite using temp.name was the method I came up with. And is there a better way to delete files after flask send_file? - I've read about using @after_this_request but Delete an uploaded file after downloading it from Flask says it may be inconsistent.

Update: to use cv2.imwrite with NamedTemporaryFile(), I had to specify the extension of the tempfile using: NamedTemporaryFile(suffix='.png') otherwise the code worked fine.

Upvotes: 1

Views: 867

Answers (2)

salparadise
salparadise

Reputation: 5805

According to this answer and running a quick test, this works as intended.

Test:

In [13]: from pathlib import Path

In [14]: from tempfile import NamedTemporaryFile

In [15]: def deltest(delete=True):
    ...:     with NamedTemporaryFile(delete=delete) as temp:
    ...:         return temp.name


In [16]: file = deltest()

In [17]: Path(file).exists()
Out[17]: False

In [18]: file = deltest(delete=False)

In [19]: Path(file).exists()
Out[19]: True

Upvotes: 1

Niloct
Niloct

Reputation: 10015

However, since I am trying to return the function in the 'with' statement, will the temp file still be deleted?

I think it is, according to https://docs.python.org/3.9/library/tempfile.html#tempfile.TemporaryFile:

The file is created securely, using the same rules as mkstemp(). It will be destroyed as soon as it is closed (including an implicit close when the object is garbage collected)

The return statement would garbage collect the temp variable and the object therefore.

The examples I've seen use temp.write but since I am using cv2.imwrite using temp.name was the method I came up with.

You can use the write method if you write an encoded string:

from tempfile import NamedTemporaryFile

def temp_fx():
  with NamedTemporaryFile() as temp:
    print(temp.name)
    temp.write('abc'.encode())
    return 1

temp_fx()

Upvotes: 1

Related Questions