#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