SDu*_*uma 8 python api starlette fastapi
我正在使用 FastAPI,目前我返回了一个 csv,我用 Pandas 从 SQL 服务器读取了它。(pd.read_sql()) 但是 csv 对于浏览器来说非常大,我想用文件响应返回它:https ://fastapi.tiangolo.com/advanced/custom-response/( 页面末尾)。我似乎无法在不首先将其写入 csv 文件的情况下执行此操作,该文件看起来很慢,并且每次请求都会使文件系统与 csv 混淆。
所以我的问题是,有没有办法从 sql 数据库或 Pandas 数据帧返回 FileResponse。
如果没有,有没有办法在客户端读取生成的 csv 文件后删除它?
谢谢你的帮助!
亲切的问候,
斯蒂芬
Tom*_*ood 26
基于此https://github.com/tiangolo/fastapi/issues/1277
from fastapi.responses import StreamingResponse
import io
@app.get("/get_csv")
async def get_csv():
df = pandas.DataFrame(dict(col1 = 1, col2 = 2))
stream = io.StringIO()
df.to_csv(stream, index = False)
response = StreamingResponse(iter([stream.getvalue()]),
media_type="text/csv"
)
response.headers["Content-Disposition"] = "attachment; filename=export.csv"
return response
Run Code Online (Sandbox Code Playgroud)
小智 8
添加到前面提到的代码中,我发现放置另一个响应标头很有用,以便客户端能够看到“Content-Disposition”。这是因为,客户端默认只能看到 CORS 安全列表中的响应标头。“Content-Disposition”不在此列表中,因此必须显式添加它https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers。
我不知道是否有另一种方法可以以更通用的方式为客户端或服务器指定这一点,以便它适用于所有必要的端点,但这就是我应用它的方式。
@router.post("/files", response_class = StreamingResponse)
async def anonymization(file: bytes = File(...), config: str = Form(...)):
# file as str
inputFileAsStr = StringIO(str(file,'utf-8'))
# dataframe
df = pd.read_csv(inputFileAsStr)
# send to function to handle anonymization
results_df = anonymize(df, config)
# output file
outFileAsStr = StringIO()
results_df.to_csv(outFileAsStr, index = False)
response = StreamingResponse(
iter([outFileAsStr.getvalue()]),
media_type='text/csv',
headers={
'Content-Disposition': 'attachment;filename=dataset.csv',
'Access-Control-Expose-Headers': 'Content-Disposition'
}
)
# return
return response
Run Code Online (Sandbox Code Playgroud)
小智 5
在这件事上我也用头撞墙。我的用例略有不同,因为我将图像、pdf 等作为 blob 存储在我的 maria 数据库中。我发现诀窍是将 blob 内容传递给 BytesIO,其余的很简单。
from fastapi.responses import StreamingResponse
from io import BytesIO
@router.get('/attachment/{id}')
async def get_attachment(id: int):
mdb = messages(s.MARIADB)
attachment = mdb.getAttachment(id)
memfile = BytesIO(attachment['content'])
response = StreamingResponse(memfile, media_type=attachment['contentType'])
response.headers["Content-Disposition"] = f"inline; filename={attachment['name']}"
return response
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7994 次 |
| 最近记录: |