You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:21:14