我正在尝试返回一个使用
openpyxl
和 FastAPI
从模板修改的 excel 文件(类型可能不相关),但我得到了 File at path C:\\Users\\user\\AppData\\Local\\Temp\\tmpg3am6f8d\\1050669-export.xlsx does not exist.
如果我转到临时文件夹,我可以看到临时目录出现(文件也在那里),但它们在执行 return 语句之前被删除。如果我在返回语句之前
print(os.path.exists(path))
,我会得到True
。
with TemporaryDirectory() as tmp:
path = os.path.join(tmp, id + "-export.xlsx")
wb.save(path)
return FileResponse(path)
有没有办法防止在 return 语句之前开始删除目录/文件?或者我应该采取其他方式吗?
您在
tempfile.TemporaryFile
块中使用 with
。这意味着当您的代码退出 with
上下文时,临时文件将被删除。这正是当您从函数中 return
时发生的情况,这就是为什么在 FastAPI 能够访问文件之前文件被删除的原因。换句话说,该行为正是您所要求的。
StreamingResponse
而不是 FileResponse
。也许是这样的:
from tempfile import TemporaryFile
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
async def temporaryFileGenerator():
with TemporaryFile() as fd:
fd.write('This is a test\n'.encode())
fd.seek(0)
while True:
data = fd.read(1024)
if not data:
break
yield data
@app.get('/example1')
async def example1():
return StreamingResponse(temporaryFileGenerator())
因为我们正在流式传输文件,而不是简单地返回文件名,所以在我们将所有字节流式传输到客户端之前,
with
块不会退出。
根据文档
TemporaryDirectory()
将在上下文结束之前删除该目录。
考虑到您的工作流程,您应该使用
mkdtemp()
函数,请记住您必须处理
删除操作。我创建了一个示例,请随意遵循
import os
from tempfile import mkdtemp, TemporaryDirectory
def define_temporal_and_ephemeral_dir() -> str:
with TemporaryDirectory() as tmp:
return tmp
def define_temporal_dir() -> str:
tmp = mkdtemp()
return tmp
if __name__ == '__main__':
# Ephemeral directory logic.
ephemeral_path = define_temporal_and_ephemeral_dir()
is_dir_exists = os.path.exists(ephemeral_path)
print(f'{ephemeral_path} exists: {is_dir_exists}\n')
assert is_dir_exists == False
# Non ephemeral directory logic.
path = define_temporal_dir()
is_dir_exists = os.path.exists(path)
print(f'{path} exists: {is_dir_exists}\n')
assert is_dir_exists == True
# The user has to be responsible to manually remove the temporal directory created.
os.rmdir(path)
is_dir_exists = os.path.exists(path)
assert is_dir_exists == False
print('Non ephemeral directory was removed.')
免责声明:我在Mac上测试了这个,希望你在Windows环境上测试时不会发现问题。
输出:
/var/folders/dm/z6w7zmj1193gcb_n0v5p04jw0000gn/T/tmp974g8vpb exists: False
/var/folders/dm/z6w7zmj1193gcb_n0v5p04jw0000gn/T/tmpbujzyodz exists: True
Non ephemeral directory was removed.