FastAPI如何同时返回JSON响应与Zip压缩包?
如何用FastAPI同时返回JSON数据和Zip压缩包?
HTTP协议规定一个请求只能对应一个响应,你原代码试图返回JSONResponse和StreamingResponse两个对象,这不符合协议规范,所以无法正常运行。此外你的代码还有两处语法问题:函数定义末尾缺冒号,result1、result2未定义。
下面提供两种可行的解决思路:
方案一:将JSON数据打包到Zip压缩包中
把JSON数据写入一个文件(比如result.json),和其他文件一起放进Zip包,用户下载后解压就能同时拿到结构化数据和文件。修改后的代码如下:
from fastapi import FastAPI, StreamingResponse from zipfile import ZipFile from io import BytesIO import glob import json app = FastAPI() @app.post("/search") async def structure_search(): # 替换为你的业务逻辑生成实际结果 result1 = "示例结果1" result2 = "示例结果2" json_response = {"item1": result1, "item2": result2} zip_io = BytesIO() with ZipFile(zip_io, mode="w", compression=zipfile.ZIP_DEFLATED) as temp_zip: # 将JSON数据写入压缩包内的文件 temp_zip.writestr("result.json", json.dumps(json_response)) # 添加目标目录下的所有文件 for fpath in glob.glob("directory/*"): temp_zip.write(fpath) # 将文件指针移到开头,确保StreamingResponse能正确读取内容 zip_io.seek(0) return StreamingResponse( zip_io, media_type="application/x-zip-compressed", headers={"Content-Disposition": "attachment; filename=results.zip"} )
方案二:返回JSON响应,附带Zip包的下载链接
先单独实现一个生成并返回Zip包的接口,主搜索接口返回JSON数据和该接口的URL,让客户端主动发起第二次请求获取压缩包。
from fastapi import FastAPI, JSONResponse, StreamingResponse from zipfile import ZipFile from io import BytesIO import glob app = FastAPI() # 专门提供Zip包下载的接口 @app.get("/download-zip") async def download_zip(): zip_io = BytesIO() with ZipFile(zip_io, mode="w", compression=zipfile.ZIP_DEFLATED) as temp_zip: for fpath in glob.glob("directory/*"): temp_zip.write(fpath) zip_io.seek(0) return StreamingResponse( zip_io, media_type="application/x-zip-compressed", headers={"Content-Disposition": "attachment; filename=results.zip"} ) # 主搜索接口,返回JSON数据和下载链接 @app.post("/search") async def structure_search(): # 替换为你的业务逻辑生成实际结果 result1 = "示例结果1" result2 = "示例结果2" return JSONResponse(content={ "item1": result1, "item2": result2, "download_url": "/download-zip" })
内容的提问来源于stack exchange,提问作者Gabriel Cretin
相关产品推荐
相关产品推荐

