I am writing a small Flask server which: 1. receives an image and saves it into a temporary directory, 2. does some processing that produces a modified image, and 3. sends back the modified image.
The structure can be summarized as:
@app.route('/process_file', methods=['POST'])
def process_file():
file = request.files['file']
with tempfile.TemporaryDirectory() as tmpdirname:
file.save(os.path.join(tmpdirname, "original.png"))
# ...
# Do a lot of stuff to produce a new "modified.png", in the same dir
# ...
ret_path = os.path.join(tmpdirname, "modified.png")
return send_file(filename_or_fp=ret_path, mimetype="image/png")
On Linux, everything works fine.
However, on Windows, we get an error message when the system tries to delete the temporary directory.
Here is a selection of the stack error we get during the deletion of the temporary directory:
File "C:\Users\hapr00\AppData\Local\Programs\Python\Python37\lib\tempfile.py", line 805, in __exit
__
self.cleanup()
File "C:\Users\hapr00\AppData\Local\Programs\Python\Python37\lib\tempfile.py", line 809, in cleanu
p
_shutil.rmtree(self.name)
File "C:\Users\hapr00\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 513, in rmtree
return _rmtree_unsafe(path, onerror)
File "C:\Users\hapr00\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 397, in _rmtree_
unsafe
onerror(os.unlink, fullname, sys.exc_info())
File "C:\Users\hapr00\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 395, in _rmtree_
unsafe
os.unlink(fullname)
PermissionError: [WinError 32] Der Prozess kann nicht auf die Datei zugreifen, da sie von einem ande
ren Prozess verwendet wird: 'path/to/the/modified.png'
Which in English is something like: "The process cannot access the file because it is used by another process."
My understanding
It looks like send_file
is asynchronous, so Python tries to delete the temporary directory while another thread is still uploading the file.
On Linux, this doesn't happen because only the filenames are deleted, while the file node will still be alive until the other thread finishes uploading the file.
Question: How would one re-organize the code to properly handle this situation?
(No, switching to a Linux server is not a solution, at least for the moment)