Flask:send_file()完成后从服务器删除文件

问题描述 投票:0回答:4

我有一个 Flask 后端,它根据一些用户输入生成图像,并使用 Flask 的

send_file()
函数将此图像发送到客户端。

这是Python服务器代码:

@app.route('/image',methods=['POST'])
def generate_image():
    cont = request.get_json()
    t=cont['text']
    print(cont['text'])
    name = pic.create_image(t) //A different function which generates the image
    time.sleep(0.5)
    return send_file(f"{name}.png",as_attachment=True,mimetype="image/png")

我想在该图像发送到客户端后从服务器删除它。

如何实现?

python-3.x flask delete-file sendfile
4个回答
6
投票

好吧,我解决了。我使用

@app.after_request
并使用 if 条件检查端点,然后删除图像

@app.after_request
def delete_image(response):
    global image_name
    if request.endpoint=="generate_image": //this is the endpoint at which the image gets generated
        os.remove(image_name)
    return response

2
投票

另一种方法是将装饰器包含在路线中。因此,您不需要检查端点。只需从

after_this_request
库导入
flask

from flask import after_this_request


@app.route('/image',methods=['POST'])
def generate_image():
    @after_this_request
    def delete_image(response):
        try:
            os.remove(image_name)
        except Exception as ex:
            print(ex)
        return response

    cont = request.get_json()
    t=cont['text']
    print(cont['text'])
    name = pic.create_image(t) //A different function which generates the image
    time.sleep(0.5)
    return send_file(f"{name}.png",as_attachment=True,mimetype="image/png")

0
投票

我和这里的其他评论者有同样的问题:

  1. @after_this_request 解决方案没有帮助,无法访问该文件。
  2. 在我看来,@app.after_request 解决方案似乎过于复杂且过于晦涩。

最后我想出了一个解决方案(抱歉,这个例子来自我的代码,所以与原来的问题有点不同):

@bp.route('/download/<int:id>')
def download(id: int):
    with db.session() as ses:
        data = ses.scalars( ... fetch data from db by id...).one_or_none()
        if session_data is None:
            abort(404, f"Data with id {id} unknown.")
        try:
            with tempfile.NamedTemporaryFile(delete=False, suffix=".tmp") as fid:
                tmp_file = Path(fid.name)
                write_data_to_file(tmp_file, data)
                fid.seek(0)
                file_content = io.BytesIO(fid.read())
        finally:
            tmp_file.unlink()

        return send_file(
            file_content,
            "application/octet-stream",
            as_attachment=True,
            download_name=f"Data_{id}.tmp")

这将从数据库获取的数据写入文件(不幸的是,在我的例子中,编写器函数只接受文件名......)。由于我的代码也必须在 Windows 上运行,因此我需要执行 delete=False ... .unlink() 技巧。如果不是这种情况,也可以让上下文管理器来完成这项工作。

实际的解决方案是将文件内容读入 io.BytesIO 缓冲区,然后在返回之前关闭并删除该文件。


-1
投票

你可以有另一个函数delete_image()并在generate_image()函数的底部调用它

© www.soinside.com 2019 - 2024. All rights reserved.