FastAPI后端如何同时返回PDF文件与JSON数据?
能否通过FastAPI的/summarize接口同时返回PDF文件与JSON数据?
可以实现,HTTP单次请求虽通常只能返回单一类型响应体,但有几种实用方案:
方案一:把JSON数据嵌入PDF元数据
生成新PDF时,用PyPDF2或ReportLab这类库把JSON信息写入PDF的自定义元字段。前端拿到PDF后,再读取元数据解析出JSON内容。
示例FastAPI代码:from fastapi import FastAPI, File, UploadFile, Form from fastapi.responses import FileResponse import PyPDF2 import json import tempfile app = FastAPI() @app.post("/summarize") async def upload_file(file: UploadFile = File(...), parameters: str = Form(...)): # 解析传入的JSON参数 params = json.loads(parameters) # 示例PDF处理逻辑(替换成你的实际生成逻辑) with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_pdf: reader = PyPDF2.PdfReader(file.file) writer = PyPDF2.PdfWriter() for page in reader.pages: writer.add_page(page) # 将JSON数据写入PDF元数据 writer.add_metadata({"custom_summary_data": json.dumps({"summary": "示例摘要内容", "status": "success"})}) writer.write(temp_pdf) temp_pdf_path = temp_pdf.name # 返回带元数据的PDF文件 return FileResponse(temp_pdf_path, media_type="application/pdf", filename="summary.pdf")前端可借助pdfjs等工具读取PDF元数据,提取出嵌入的JSON。
方案二:返回包含PDF和JSON的ZIP压缩包
分别生成PDF文件和JSON数据文件,打包成ZIP后返回。前端下载ZIP解压就能拿到两个文件。
示例FastAPI代码:from fastapi import FastAPI, File, UploadFile, Form from fastapi.responses import FileResponse import json import tempfile import zipfile app = FastAPI() @app.post("/summarize") async def upload_file(file: UploadFile = File(...), parameters: str = Form(...)): params = json.loads(parameters) # 生成临时PDF文件(示例逻辑) with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_pdf: temp_pdf.write(b"实际生成的PDF内容") pdf_path = temp_pdf.name # 生成JSON数据文件 json_data = {"summary": "示例摘要内容", "used_parameters": params} with tempfile.NamedTemporaryFile(delete=False, suffix=".json") as temp_json: json.dump(json_data, temp_json) json_path = temp_json.name # 打包成ZIP with tempfile.NamedTemporaryFile(delete=False, suffix=".zip") as temp_zip: with zipfile.ZipFile(temp_zip, "w") as zipf: zipf.write(pdf_path, "summary.pdf") zipf.write(json_path, "summary_info.json") zip_path = temp_zip.name # 返回ZIP压缩包 return FileResponse(zip_path, media_type="application/zip", filename="summary_package.zip")方案三:先返回JSON,附带PDF下载链接
先生成PDF并存在服务器(或云存储),返回的JSON里包含PDF的下载地址,前端拿到JSON后再单独请求下载PDF。这种方式适合大体积PDF的场景。
示例FastAPI代码:from fastapi import FastAPI, File, UploadFile, Form from fastapi.responses import JSONResponse import json import tempfile import os app = FastAPI() # 创建临时PDF存储目录 PDF_STORAGE = "./temp_pdfs" os.makedirs(PDF_STORAGE, exist_ok=True) @app.post("/summarize") async def upload_file(file: UploadFile = File(...), parameters: str = Form(...)): params = json.loads(parameters) # 生成PDF并保存到存储目录 pdf_filename = f"summary_{os.urandom(8).hex()}.pdf" pdf_path = os.path.join(PDF_STORAGE, pdf_filename) with open(pdf_path, "wb") as f: f.write(b"实际生成的PDF内容") # 返回JSON,包含PDF下载链接 return JSONResponse(content={ "status": "success", "summary": "示例摘要内容", "pdf_download_url": f"/download-pdf/{pdf_filename}" }) # 新增PDF下载接口 @app.get("/download-pdf/{filename}") async def download_pdf(filename: str): pdf_path = os.path.join(PDF_STORAGE, filename) return FileResponse(pdf_path, media_type="application/pdf", filename=filename)
内容的提问来源于stack exchange,提问作者Forshank
相关产品推荐
相关产品推荐

