Flask: удаление файла в декораторе @after_this_request не работает. Файл используется другим процессом - PullRequest
0 голосов
/ 09 июля 2020

Привет, я хочу загрузить zip-файл, а затем удалить его после завершения загрузки.

@app.route('/download',methods=['GET', 'POST'])
def download():
    projectTitle = request.args.get('projectTitle')
    file_path = projectTitle+".zip"

    @after_this_request
    def remove_file(response):
        print("After this request...")
        os.remove(file_path)
        return response

    return send_file(file_path,
                 mimetype='application/zip',
                 attachment_filename=file_path,
                 as_attachment=True)

Я вызываю эту конечную точку с помощью javascript:

function downloadURI(uri) 
{
    var link = document.createElement("a");
    link.href = uri;
    link.target = "_blank";
    link.click();
}

downloadURI("download?projectTitle="+title);

zip файл никогда не удаляется, что мне не хватает?


EDIT: Я немного отладил и заметил, что получаю следующую ошибку:

After this request...
After this request...
[2020-07-10 13:00:40,653] ERROR in app: Exception on /download [GET]
Traceback (most recent call last):
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 1953, in full_dispatch_request
    return self.finalize_request(rv)
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 1970, in finalize_request
    response = self.process_response(response)
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 2267, in process_response
    response = handler(response)
  File "C:/Users/ceccolig/PycharmProjects/SingleBP/app.py", line 39, in remove_file
    os.remove(file_path)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'DemoTMD-prod.zip'
[2020-07-10 13:00:40,656] ERROR in app: Request finalizing failed with an error while handling an error
Traceback (most recent call last):
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 1953, in full_dispatch_request
    return self.finalize_request(rv)
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 1970, in finalize_request
    response = self.process_response(response)
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 2267, in process_response
    response = handler(response)
  File "C:/Users/ceccolig/PycharmProjects/SingleBP/app.py", line 39, in remove_file
    os.remove(file_path)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'DemoTMD-prod.zip'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 1970, in finalize_request
    response = self.process_response(response)
  File "C:\Users\ceccolig\PycharmProjects\SingleBP\venv\lib\site-packages\flask\app.py", line 2267, in process_response
    response = handler(response)
  File "C:/Users/ceccolig/PycharmProjects/SingleBP/app.py", line 39, in remove_file
    os.remove(file_path)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'DemoTMD-prod.zip'
127.0.0.1 - - [10/Jul/2020 13:00:40] "GET /download?projectTitle=DemoTMD-prod HTTP/1.1" 500 -

Как вы видите, @after_this_request вызывается (я не знаю почему) два раза, фактически «После этого запроса» печатается два раза.

1 Ответ

0 голосов
/ 15 июля 2020

Как вы видите, когда вызывается декорированный метод @after_this_request, срок действия этого запроса не закончился, и клиент все еще ждет ответа, поэтому файл все еще открывается, или вы можете сказать, что он используется, чтобы вы могли Не удалять файл.

Ну вот и моё решение. Точно так же:

from stuff import celery_app


@celery_app.task(queue='some_specific_queue')
def delete_files(filepath):
    try:
        os.remove(filepath)
    except FileNotFoundError:
        # some other stuff

И в вашем api вы можете опубликовать sh эту задачу, например, :

import datetime


@app.route('/download',methods=['GET', 'POST'])
def download():
    projectTitle = request.args.get('projectTitle')
    file_path = projectTitle+".zip"

    delete_files.apply_async(
        args=(file_path), 
        eta=datetime.datetime.utcnow()+datetime.timedelta(hours=4)
    )

    return send_file(file_path,
                 mimetype='application/zip',
                 attachment_filename=file_path,
                 as_attachment=True)

Я не знаю, как у людей ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...