微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在`return FileResponsefile_path`之后删除文件

如何解决如何在`return FileResponsefile_path`之后删除文件

我正在使用FastAPI接收图像,对其进行处理,然后将图像作为FileResponse返回。

但是返回的文件是临时文件,在端点返回文件后需要删除

@app.post("/send")
async def send(imagem_base64: str = Form(...)):

    # Convert to a Pillow image
    image = base64_to_image(imagem_base64)

    temp_file = tempfile.mkstemp(suffix = '.jpeg')
    image.save(temp_file,dpi=(600,600),format='JPEG',subsampling=0,quality=85)

    return FileResponse(temp_file)

    # I need to remove my file after return it
    os.remove(temp_file)

返回文件后如何删除文件

解决方法

您可以删除background task中的文件,因为该文件将在发送响应后 运行。

import os
import tempfile

from fastapi import FastAPI
from fastapi.responses import FileResponse

from starlette.background import BackgroundTasks

app = FastAPI()


def remove_file(path: str) -> None:
    os.unlink(path)


@app.post("/send")
async def send(background_tasks: BackgroundTasks):
    fd,path = tempfile.mkstemp(suffix='.txt')
    with os.fdopen(fd,'w') as f:
        f.write('TEST\n')
    background_tasks.add_task(remove_file,path)
    return FileResponse(path)

另一种方法是使用dependency with yieldfinally块代码将在发送响应之后甚至在完成所有后台任务之后执行。

import os
import tempfile

from fastapi import FastAPI,Depends
from fastapi.responses import FileResponse


app = FastAPI()


def create_temp_file():
    fd,'w') as f:
        f.write('TEST\n')
    try:
        yield path
    finally:
        os.unlink(path)


@app.post("/send")
async def send(file_path=Depends(create_temp_file)):
    return FileResponse(file_path)

注意mkstemp()返回带有文件描述符和路径的元组。

,

您可以将清理任务作为 FileResponse 的参数传递:

from starlette.background import BackgroundTask

# ...

def cleanup():
    os.remove(temp_file)

return FileResponse(
    temp_file,background=BackgroundTask(cleanup),)
,

在您的情况下,返回StreamingResponse是一个更好的选择,并且由于文件操作将阻止事件循环的整个执行,因此可以提高内存效率。

由于您接收的数据为b64encoded。您可以将其读取为字节,然后从中返回StreamingResponse

from fastapi.responses import StreamingResponse
from io import BytesIO

@app.post("/send")
async def send(imagem_base64: str = Form(...)):
    in_memory_file = BytesIO()
    image = base64_to_image(imagem_base64)
    image.save(in_memory_file,dpi=(600,600),format='JPEG',subsampling=0,quality=85)
    in_memory_file.seek(0)
    return StreamingResponse(in_memory_file.read(),media_type="image/jpeg")

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?