FastAPI如何返回多媒体类型响应并适配Swagger文档展示
FastAPI接口同时返回图片与关键点数据实现方案
HTTP单次响应无法直接混合返回两种独立Content-Type的内容,要实现img_show和points_show同时为True时返回两类数据,有两种可落地的实现方案,均兼容FastAPI自带Swagger文档的正常展示与调试。
方案1:Base64嵌入JSON返回(优先推荐)
整个响应为标准JSON格式,Swagger可以直接完整展示所有返回字段,前端不需要做特殊的响应解析,拿到图片Base64串后可以直接赋值给img标签渲染,联调成本最低。
注意:该方案因为Base64编码特性,图片体积会比原始二进制大33%左右,普通业务场景下这个开销完全可接受。
分支实现代码
先提前导入依赖:
import base64
对应判断分支内容:
if img_show and points_show: # 编码图片为JPEG格式后转Base64字符串 _, img_encode = cv2.imencode('.jpg', canvas) img_base64_str = base64.b64encode(img_encode.tobytes()).decode("utf-8") # 组装统一JSON结构返回 return { "keypoints1": {f"Body{i+1}": points1[i] for i in range(len(points1))}, "keypoints2": points2, "result_image": f"data:image/jpeg;base64,{img_base64_str}" }
方案2:multipart/form-data混合响应
如果返回图片分辨率高、对传输带宽敏感,可以用多部分响应格式,把JSON关键点数据和JPEG图片二进制作为两个独立分段放在同一个响应中,不会产生Base64的额外体积开销。
分支实现代码
不需要额外安装依赖,直接用Starlette自带的Response类构造即可:
from starlette.responses import Response import json
对应判断分支内容:
if img_show and points_show: # 编码图片为JPEG字节流 _, img_bytes = cv2.imencode('.jpg', canvas) img_bytes = img_bytes.tobytes() # 构造关键点数据 kp_data = { "keypoints1": {f"Body{i+1}": points1[i] for i in range(len(points1))}, "keypoints2": points2 } # 构造multipart响应体 boundary = "----FastAPIMixedBoundary7890" response_body = ( f"--{boundary}\r\n" f"Content-Disposition: form-data; name=\"keypoints\"\r\n" f"Content-Type: application/json\r\n\r\n" f"{json.dumps(kp_data)}\r\n" f"--{boundary}\r\n" f"Content-Disposition: form-data; name=\"result_img\"; filename=\"detect_result.jpg\"\r\n" f"Content-Type: image/jpeg\r\n\r\n" ).encode("utf-8") + img_bytes + f"\r\n--{boundary}--\r\n".encode("utf-8") return Response( content=response_body, media_type=f"multipart/form-data; boundary={boundary}" )
注意:该方案在Swagger中调试时,可以分别查看JSON段内容、下载图片段,前端需要按标准multipart格式解析响应拿到两类数据。
额外优化建议
原代码中points_show分支返回的是元组包裹的两个独立字典,会导致FastAPI无法自动生成准确的响应结构Schema,建议调整为单个字典返回,方便Swagger正确识别:
elif points_show: return { "keypoints1": {f"Body{i+1}": points1[i] for i in range(len(points1))}, "keypoints2": points2 }
内容的提问来源于stack exchange,提问作者Ali Amini Bagh
相关产品推荐
相关产品推荐

