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

Vercel Python无服务器函数返回流时触发FUNCTION_INVOCATION_TIMEOUT问题

解决Vercel上Python FastAPI流式转发超时问题

问题分析

在Vercel环境中,使用Python FastAPI的StreamingResponse转发第三方流时,若流持续超过10秒会触发FUNCTION_INVOCATION_TIMEOUT错误,但Node.js通过fetch直接返回流却能正常运行。核心原因是Vercel对Python函数默认设置了10秒超时,且Python的流式响应处理会让函数进程持续运行至流结束;而Node.js的fetch响应透传机制被Vercel优化,不会轻易触发超时。

解决方案

方案1:调整Vercel函数超时配置

在vercel.json中为Python函数设置更长的超时时间(Vercel允许最大900秒),给流转发预留足够时长:

{
  "builds": [
    { "src": "main.py", "use": "@vercel/python" },
    { "src": "stream.js", "use": "@vercel/node"}
  ],
  "routes": [
    {"src": "/api/(.*)", "dest": "main.py"},
    {"src": "/stream/(.*)", "dest": "stream.js"}
  ],
  "functions": {
    "main.py": {
      "maxDuration": 60
    }
  }
}

方案2:优化Python流式转发代码

确保第三方响应的头信息完整透传,让StreamingResponse以更高效的方式传输数据,减少函数进程阻塞:

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import httpx

app = FastAPI()

@app.get("/api/stream/{url:path}")
async def forward_stream(url: str):
    async with httpx.AsyncClient(http2=True) as client:
        request = client.build_request("GET", f"https://{url}")
        async with client.send(request, follow_redirects=True, stream=True) as response:
            # 透传第三方响应的状态码和头信息
            headers = dict(response.headers)
            # 移除流式响应不需要的固定长度头
            headers.pop("Content-Length", None)
            
            return StreamingResponse(
                response.aiter_raw(),
                status_code=response.status_code,
                headers=headers,
                media_type=response.headers.get("Content-Type")
            )

关键优化点

  • 透传Transfer-Encoding: chunked等流式相关头,让Vercel明确识别这是流式响应
  • 使用async with管理客户端连接,避免资源泄漏
  • 移除Content-Length头,防止Vercel等待完整响应内容

方案3:使用Starlette底层响应类

若FastAPI的StreamingResponse仍有问题,可尝试直接用Starlette的底层响应类,贴近Node.js的fetch透传逻辑:

from starlette.responses import Response

# 替换接口中的返回逻辑
return Response(
    content=response.aiter_raw(),
    status_code=response.status_code,
    headers=headers,
    media_type=response.headers.get("Content-Type")
)

内容的提问来源于stack exchange,提问作者gdlk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:20:31