vercel 部署 python 函数需正确配置 vercel.json(根目录)、builds 指定 src 和 "@vercel/python"、handler 签名必须为 def handler(event, context),返回含 statuscode 和字符串 body 的字典,依赖由 requirements.txt 声明,body 需 decode 后解析。

Python 函数在 Vercel 上跑不起来:vercel.json 配置错在哪
Vercel 默认不认 Python,必须显式声明运行时和入口。没配 vercel.json 或路径写错,直接 404 或 502 —— 不是代码问题,是根本没进你的函数。
-
vercel.json必须放在项目根目录,不是src/或api/下 -
builds字段不能省:必须指定src(函数文件路径)和use(运行时),例如"use": "@vercel/python" -
src路径是相对于项目根的,比如函数在api/hello.py,就写"src": "api/hello.py",不是"src": "./api/hello.py"或"src": "hello.py" -
config里不要加runtime字段 ——@vercel/python自带 runtime,加了反而报Unknown runtime
Python handler 函数签名不对:为什么 Vercel 总报 handler is not callable
Vercel 的 Python 运行时只认一个固定签名:def handler(event, context)。名字不能改,参数不能少,类型不能乱套。
- 函数名必须叫
handler,不能是main、lambda_handler或其他 - 必须且仅接收两个参数:
event(dict,含 HTTP 方法、headers、body 等)和context(当前无实际用途,但必须存在) - 返回值必须是 dict,且至少包含
"statusCode"和"body"字段;body必须是字符串,JSON 要自己json.dumps() - 别在顶层 import 失败的包(比如
numpy),Vercel 构建阶段就失败,不会等到调用handler
示例最小可用函数:
import json
def handler(event, context):
return {
"statusCode": 200,
"body": json.dumps({"message": "ok"})
}
本地开发和 Vercel 行为不一致:依赖安装和路径问题
本地跑得通,部署后 ModuleNotFoundError 或读不到文件,大概率是依赖没进构建上下文,或路径假设错了。
最权威的 Python 教程,由 Python 作者 Guido van Rossum 主笔,有少许学院味道。中文电子版由刘鑫、李梦夷、Kernel1983 翻译。 文件内容为中英双语。 作者简介: Guido van Rossum是Python编程语言的创始人,现在就职于Google公司,但在他的大部分时间里他都还在为Python语言的发展而努力。自1989年Guido在ABC与语言的基础上创建了Python语言,目前这门语言不仅得到其他开发社区的认可,比如JPython和IronPython的广泛应用
-
requirements.txt必须在项目根目录,且每行一个包,不能有注释或空行 —— Vercel 构建时只认这个文件,不执行pip install -e . - 所有 Python 文件(包括
handler引用的模块)必须在src指定路径的同一级或子目录下;跨目录导入(比如从根目录 import)会失败 - 别用相对路径读取静态文件(如
open("data.json"))—— 构建后工作目录不确定;改用os.path.join(os.path.dirname(__file__), "data.json") - Vercel 构建环境是 Linux + Python 3.9(截至 2024 年中),本地用 3.11 或 Windows 的行为差异(如路径分隔符、大小写敏感)会暴露出来
HTTP 请求体解析失败:body 是二进制还是字符串?
Vercel 把原始请求 body 当作 bytes 传给 event["body"],但很多人直接当字符串用,结果 json.loads(event["body"]) 报 TypeError: expected string or bytes-like object。
立即学习“Python免费学习笔记(深入)”;
-
event["body"]类型取决于请求是否带Content-Type: application/json—— 实际上 Vercel 总传bytes,不管 header - 安全做法:先检查
event.get("body")是否为None,再用event["body"].decode("utf-8")转成字符串,再json.loads() - 如果前端发的是 form-data 或 urlencoded,
body是 URL 编码字符串,不是 JSON,需用urllib.parse.parse_qs()解析 -
event["httpMethod"]才是真正的请求方法,别信event["method"](它不存在)
真正卡住人的,往往不是语法,而是 Vercel 把 Python 当“二等公民”来对待:没有调试日志实时输出、构建缓存不透明、错误堆栈被截断。多看 vercel logs --debug 输出,而不是只盯着控制台那句 Function invocation failed。









