Удалите файл после того, как колба подаст его

#python #flask

Вопрос:

У меня есть представление колбы, которое генерирует данные и сохраняет их в виде CSV-файла с Панд, а затем отображает данные. Второй вид служит для сгенерированного файла. Я хочу удалить файл после его загрузки. Мой текущий код вызывает ошибку разрешения, возможно, потому after_request , что удаляет файл до того, как он будет обработан send_from_directory . Как я могу удалить файл после его обслуживания?

 def process_data(data)  tempname = str(uuid4())   '.csv'  data['text'].to_csv('samo/static/temp/{}'.format(tempname))  return file  @projects.route('/getcsv/lt;filegt;') def getcsv(file):  @after_this_request  def cleanup(response):  os.remove('samo/static/temp/'   file)  return response   return send_from_directory(directory=cwd   '/samo/static/temp/', filename=file, as_attachment=True)  

Ответ №1:

after_request выполняется после возврата представления, но до отправки ответа. При отправке файла может использоваться потоковый ответ; если вы удалите его до того, как он будет полностью прочитан, вы можете столкнуться с ошибками.

В основном это проблема в Windows, другие платформы могут пометить удаленный файл и хранить его до тех пор, пока к нему не будет получен доступ. Тем не менее, все равно может быть полезно удалить файл только после того, как вы убедитесь, что он был отправлен, независимо от платформы.

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

 @app.route('/download_and_remove/lt;filenamegt;') def download_and_remove(filename):  path = os.path.join(current_app.instance_path, filename)   def generate():  with open(path) as f:  yield from f   os.remove(path)   r = current_app.response_class(generate(), mimetype='text/csv')  r.headers.set('Content-Disposition', 'attachment', filename='data.csv')  return r