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

通过AWS API Gateway+Python Mangum返回二进制响应失败求助

关于Mangum二进制响应配置的问题

我按照Mangum文档中二进制响应的默认配置说明操作,但始终无法实现二进制响应功能,客户端收到的一直是base64编码的数据。我的理解是Mangum应该自动识别非text_mime_types的Content-Type,将响应的isBase64Encoded设为true,让API Gateway转换为二进制数据返回给客户端,但实际没生效。

我的代码如下:

import random
    
from fastapi import APIRouter, Response
from fastapi.middleware.gzip import GZipMiddleware
    
router = APIRouter(tags=['public'])
    
app = create_app()
app.add_middleware(GZipMiddleware, minimum_size=1000)
    
# AWS Lambda support
handler = Mangum(app, lifespan="off")
    

@router.get("/update/{current_state}/download")
async def download_something_binary() -> Response:
    # Create some random bytes
    import random
    open('/tmp/data', 'wb').write(random.randbytes(1024 * 100))

    # Return the binary payload
    f = open('/tmp/data', 'rb')
    return Response(
        status_code=200,
        content=f.read(), headers={
                "Content-Type": "application/octet-stream",
                "Content-Disposition": "attachment; filename=data.tar.gz"})

我还尝试过直接返回字典,但结果还是一样。请问是我的理解有误还是操作出错?


排查与解决要点

  • 检查Mangum版本
    旧版本的Mangum在二进制响应处理上可能存在问题,确保使用最新稳定版:

    pip install --upgrade mangum
    
  • 显式配置二进制MIME类型
    避免自动识别的偏差,直接指定binary_mime_types:

    handler = Mangum(
        app,
        lifespan="off",
        binary_mime_types=["application/octet-stream"]
    )
    

    或者从默认文本类型中排除对应类型:

    handler = Mangum(
        app,
        lifespan="off",
        text_mime_types=Mangum.DEFAULT_TEXT_MIME_TYPES - {"application/octet-stream"}
    )
    
  • 配置API Gateway二进制媒体类型
    即使Mangum设置了isBase64Encoded,API Gateway也需同步配置:

    1. 进入API Gateway控制台,选择目标API
    2. 切换到设置选项卡,在二进制媒体类型中添加application/octet-stream
    3. 重新部署API使配置生效
  • 排查GZip中间件的影响
    GZip压缩可能干扰Mangum的二进制识别逻辑,可先移除中间件测试,若正常再调整:

    • 针对该路由禁用GZip(FastAPI 0.95+支持)
    @router.get(
        "/update/{current_state}/download",
        responses={200: {"content": {"application/octet-stream": {}}}},
        middleware=[{"middleware_class": GZipMiddleware, "minimum_size": 1000, "exclude_paths": ["/update/{current_state}/download"]}]
    )
    
    • 或在响应中添加Vary头避免缓存问题
  • 修复文件操作的资源泄漏
    使用with语句确保文件正确关闭,避免读取不完整:

    async def download_something_binary() -> Response:
        # 生成随机字节
        with open('/tmp/data', 'wb') as f:
            f.write(random.randbytes(1024 * 100))
        
        # 读取并返回二进制内容
        with open('/tmp/data', 'rb') as f:
            content = f.read()
        
        return Response(
            status_code=200,
            content=content, 
            headers={
                "Content-Type": "application/octet-stream",
                "Content-Disposition": "attachment; filename=data.tar.gz"
            }
        )
    

内容的提问来源于stack exchange,提问作者Jakob Simon-Gaarde

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 22:34:59