【发布时间】:2022-09-25 16:59:23
【问题描述】:
我试图请求从服务器接收一个大文件/tar.gz 文件,在服务器的代码中我只是验证文件路径,然后使用 Starlette.FileResponse 返回整个文件——就像我已经在这里搜索了很多问题。
服务器:
return FileResponse(path=file_name, media_type=\'application/octet-stream\', filename=file_name)
之后它在 pydantic 中发现错误:
File \"/usr/local/lib/python3.10/dist-packages/fastapi/routing.py\", line 149, in serialize_response
return jsonable_encoder(response_content)
File \"/usr/local/lib/python3.10/dist-packages/fastapi/encoders.py\", line 130, in jsonable_encoder
return ENCODERS_BY_TYPE[type(obj)](obj)
File \"pydantic/json.py\", line 52, in pydantic.json.lambda
UnicodeDecodeError: \'utf-8\' codec can\'t decode byte 0x8b in position 1: invalid start byte
我也尝试使用 StreamResponse 但出现了一些错误。还有其他方法吗?
我的代码中的流式响应:
@x.post(\"/download\")
async def download(file_name=Body(), token: str | None = Header(default=None)):
file_name = file_name[\"file_name\"]
# should be something like xx.tar
def iterfile():
with open(file_name,\"rb\") as f:
yield from f
return StreamingResponse(iterfile(),media_type=\'application/octet-stream\')
好的,这里是这个问题的更新。 我发现这个api上没有发生错误,但是这个api正在做转发请求。
@(\"/\")
def f():
req = requests.post(url =\"/download\")
return req.content
在这里,如果我返回一个带有 tar 文件的流响应,它会导致(可能)编码问题。
使用其他请求时,请记住设置相同的媒体类型。这里是 media_type=\'application/octet-stream\'。它有效!
-
我检查了这个答案并使用了 StreamingResponse。由于文件类型不同,我没有设置具体的 media_type。代码就像
return StreamingResponse(iterfile())我仍然得到错误:No json object could be decoded下载 tar 文件时 -
您是否尝试为 StreamingResponse 设置
media_type=\'application/octet-stream\'以表明它是二进制数据?你有失败的示例代码吗? -
这只是我放入数据主体的内容。实际名称是绝对文件路径,如 /opt/123.tar。我尝试了其他一些文件,如 syslog 或 json 文件,它们都有效。
-
在
yield from f中,我发现这可能会占用大量 CPU。我该如何解决?可能是因为chunk size小导致文件操作量大?我可以在这里增加块大小吗?
标签: python fastapi pydantic starlette