很多想用Python操作飞书多维数据表格的同学,倒下的地方往往不是代码,而是最前面那道权限门槛。我最早接触飞书开放平台的时候,也是照着别人的文章直接调接口,第一次请求就收到一串报错,回头看才发现:应用没创建、权限没勾、Token没换——三道坎全卡在同一关。这个系列的第一篇,就专门解决这个“起步即劝退”的问题:一步步打开飞书开放平台的API权限,创建企业自建应用,拿到App ID和App Secret,成功换取tenant_access_token。整个过程不写业务代码,只点鼠标加复制粘贴,但它是后面所有Python操作多维数据表格教程的绝对地基。
1. 为什么会有这个系列:手动改表改到崩溃之后
1.1 教程一上来就写Python,其实是最大的劝退点
我见过不少想用脚本批量更新多维表格的人:运营同学每天把外部表格的数据一条条复制到飞书多维表格里,偶尔还要按状态批量打个标签;开发同学想定时把数据库里的记录同步成表格行;产品经理想把用户的反馈自动归档成一张看板。大家的诉求都一样——别再让我手动点了。
但市面上的教程常做一件事:开头先扔一段requests代码。对有一点Python基础的人来说,这段代码看着不难,可一运行就报错。为什么?因为API请求需要一个前置条件:你得证明“这个应用有资格访问这个表格”。这个证明链路上有应用凭证、权限声明、Token三个环节,任意一环没对上,代码写得再漂亮也是空转。
所以我把系列教程的第一篇专门留给“权限链路”。这一篇不讲任何操作表格数据的代码,只做一件事:把飞书开放平台的API权限完整打开,让你亲手拿到一串Token。这串Token就像一张临时通行证,后续每个请求都要把它放在HTTP请求头里。
1.2 这篇保姆教程的终点:你手里多一长串token
整篇文章走完以后,你的电脑上能跑出一行类似这样的输出:
获取成功,token:t-xxxxxxxxxxxxxxxx 有效时长(秒):7200这就是本篇唯一的“胜利画面”。为了走到这一步,你需要依次完成四件事:
- 在飞书开放平台创建一个企业自建应用;
- 在权限管理里给这个应用开通多维表格相关权限;
- 发布应用版本,必要时让企业管理员审核通过;
- 用App ID和App Secret请求认证接口,换取tenant_access_token。
建议第一次操作时拿一张纸,每完成一步划掉一步。因为流程里有很多页面和按钮,稍不留神就会漏掉其中一环,回头排查时最费时间的就是“不知道哪一步没做”。
2. 动手前的三样准备:账号、控制台入口,以及两个概念
2.1 账号准备:你需要一个企业管理员能说得上话的飞书账号
首先确认你登录飞书开放平台用的账号属于你要操作的那个企业(团队)。个人版的飞书账号、或者没有管理员关系的账号,后面在创建应用、发布版本时都会卡住。
这个账号需要具备的权限很简单:
- 能进入飞书开放平台的控制台;
- 有权限创建企业自建应用;
- 有权限提交应用发布(如果不确定,找企业管理员帮忙审核)。
我自己第一次操作时用的是部门助理的账号,权限管理页面打不开,折腾半天才发现是账号身份不够。后来学乖了:凡是涉及“创建应用”这种操作,先用企业管理员身份登录,或者提前和管理员打招呼,免得流程走一半卡在审批上。
2.2 分清“企业自建应用”和“应用商店应用”,这篇只需要前一种
在飞书开放平台创建应用时,你会看到几种应用类型。这里不需要纠结,直接选企业自建应用。
“企业自建应用”是给当前企业自己内部使用的,App ID、App Secret、权限声明都由你自己控制,适合做后台脚本、内部工具、数据同步这类场景。“应用商店应用”是发布给外部企业使用的,涉及上架审核、代开发授权等一大堆流程,个人做自动化脚本完全没必要碰。
| 对比维度 | 企业自建应用 | 应用商店应用 |
|---|---|---|
| 适用场景 | 自己企业内部使用、脚本自动化 | 对外发布、多企业使用 |
| 创建方式 | 控制台直接创建 | 需要提交应用商店审核 |
| 权限管理 | 自己配置、管理员审核 | 需要走应用发布流程 |
| 学习成本 | 低 | 高 |
2.3 API权限的本质:一张门禁卡,一把一把配钥匙
很多人第一次看到“权限管理”页面会懵:为什么创建完应用还不够,还要单独去开权限?把“应用”类比成一张门禁卡就很好理解了。
门禁卡本身只是一张卡,能不能进入某个房间,取决于这张卡上配了哪几把钥匙。飞书开放平台的逻辑一样:应用创建出来,不等于它能访问任何企业数据;你得在“权限管理”里明确声明它需要读取或写入哪些资源,比如多维表格、云文档、通讯录等等。声明之后还要“发布版本”,相当于把配好的钥匙正式装进卡里;管理员审核则是门卫再核对一遍。
这个设计是为了安全:应用能访问什么、不能访问什么,全部在管理端可见、可追溯。理解了这层逻辑,后面遇到“我有应用为什么还是403”的报错,你就能快速定位——大概率是钥匙没配全或者没正式发卡。
3. 实际操作:从创建应用到发布版本,全程零代码
3.1 创建企业自建应用:入口、名称、图标的那点讲究
打开飞书开放平台控制台,登录后找到“创建应用”或“开发者后台”的入口,选择“企业自建应用”。填的表单很简单,通常包括:
- 应用名称:建议起一个能看懂用途的名字,比如“内部数据同步助手”;
- 应用描述(可选):写一句话说明这个应用干嘛用;
- 应用图标(可选):不传也能创建成功。
应用名称会显示在飞书客户端的应用目录里,别随便填成“测试123”,后面企业里其他人看到会困惑。创建成功之后,你会进入应用详情页,这时候注意看“凭证与基础信息”里的App ID,格式通常是cli_开头的字符串,记下来,后面要用。
3.2 在权限管理里找到多维表格,勾选“编辑”权限
进入左侧菜单的“权限管理”,在搜索框输入“多维表格”,会看到和Bitable相关的权限项。这里最核心的两个权限:
| 控制台里的权限名称 | 权限代码(参考) | 作用 | 适用场景 |
|---|---|---|---|
| 查看多维表格 | bitable:app:readonly | 只能读取表格结构、字段、记录 | 只做数据导出、只读监控 |
| 查看、评论、编辑和管理多维表格 | bitable:app | 可读可写,支持新增、修改、删除记录 | 数据同步、批量更新、自动化写入 |
我个人的建议:如果目标是“用Python编辑多维表格”,直接勾选“编辑和管理”那个权限,不要只勾“查看”。因为很多接口(比如新增记录、更新字段)要求的是读写权限,只开只读权限后面一定会遇到“permission denied”,到时候再返回补权限又要重新发布版本,来回多等一次审核。
3.3 发布版本:只勾权限不发布,等于白干
这是整个流程里最容易被忽略的一步,也是新手报错率最高的地方之一。你勾完了权限,如果不去“版本管理与发布”里创建一个新版本,应用在线上运行的仍然是旧配置,新勾的权限根本不生效。
操作路径大概是:进入应用详情 → 版本管理与发布 → 创建版本 → 填写版本号和更新说明 → 提交发布。
提交之后有两种情况:
- 如果你的账号有管理员权限,发布可以即时通过;
- 如果不是管理员,发布申请会进企业管理员那边,需要等他审核。
提示:改权限、改应用名称、改可见范围之后,都要重新发布版本。这个动作非常容易忘,建议把它写进自己的操作清单里。
有的教程只会让你“勾选权限”,不会提醒你发布。这一步不做,前面全白忙。
3.4 凭证与基础信息页:App ID和App Secret长在哪
回到应用详情页,找“凭证与基础信息”。这里你会看到两个关键信息:
- App ID:
cli_开头,相当于应用的公开标识; - App Secret:一串较长的密钥,相当于应用的密码,点击“查看”或“重置”才能看到。
App ID和App Secret是一对,换Token的时候要一起用。App Secret的敏感等级很高,谁拿到它,谁就能代表你的应用调用API。建议绝不把它提交到代码仓库,哪怕私有仓库也不要放。正确做法是放到本机环境变量里,或者使用密钥管理服务。
处理方式示例(Windows PowerShell/Linux/macOS通用思路):
export FEISHU_APP_ID="cli_xxxxxxxxxxxx" export FEISHU_APP_SECRET="你的App Secret"Python脚本里再通过os.getenv()读取,这样代码文件里永远不会出现密钥明文。
4. 拿到凭证后的第一个请求:换一张“通行证”Tenant Access Token
4.1 为什么后台脚本要用tenant_access_token,别碰user_token
飞书开放平台的Token有两种常见形态:tenant_access_token和user_access_token。
- tenant_access_token:以“租户”(可以理解为企业/团队)身份发起请求,代表“这个应用在替整个企业访问资源”,适合定时任务、后台脚本、服务端数据同步;
- user_access_token:以“某个用户”身份发起请求,需要走OAuth授权流程,让用户点同意、跳转授权页、再回调拿Token,对无人值守的脚本来说非常麻烦。
所以,本系列教程里所有Python调用都用tenant_access_token。对操作多维表格的场景来说,这个Token已经够用,而且不需要用户参与授权。
4.2 调用认证接口:参数、返回结构、Python代码
飞书开放平台获取tenant_access_token的接口是auth/v3/tenant_access_token/internal,HTTP方法是POST,请求体是JSON格式,字段如下:
| 字段 | 说明 |
|---|---|
| app_id | 应用凭证,cli_开头 |
| app_secret | 应用密钥 |
写Python代码之前,先确认本机装好requests库:
pip install requests完整示例代码:
import requests url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" payload = { "app_id": "cli_xxxxxxxxxxxx", "app_secret": "你的App Secret" } resp = requests.post(url, json=payload) data = resp.json() if data.get("code") == 0: print("获取成功,token:", data["tenant_access_token"]) print("有效时长(秒):", data["expire"]) else: print("获取失败:", data.get("msg"))运行之后能看到类似输出:
获取成功,token:t-xxxxxxxxxxxxxxxx 有效时长(秒):7200code为0表示成功,其他非0值表示失败。最常见的失败原因是app_id或app_secret填错,返回的msg里会直接提示。
也可以用curl快速验证:
curl -X POST 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal' \ -H 'Content-Type: application/json' \ -d '{"app_id":"cli_xxxx","app_secret":"你的App Secret"}'4.3 Token的存活时间与缓存策略:别每次都去刷新
tenant_access_token的有效期由接口返回的expire字段决定,一般是7200秒(2小时)。过期之后Token失效,需要重新获取。
这里有一个实际工程问题:如果每调用一次接口就重新请求一次Token,等于白白多发很多认证请求,也没必要。正确做法是把Token缓存在内存变量里,等快过期了再刷新。
一个简单可用的缓存写法:
import time import requests TOKEN_CACHE = { "value": "", "expire_at": 0, } def get_tenant_access_token(app_id: str, app_secret: str) -> str: # 提前60秒过期,避免边界时间误差 if TOKEN_CACHE["value"] and TOKEN_CACHE["expire_at"] > time.time() + 60: return TOKEN_CACHE["value"] url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" resp = requests.post(url, json={ "app_id": app_id, "app_secret": app_secret, }) data = resp.json() if data.get("code") != 0: raise RuntimeError(f"获取tenant_access_token失败:{data.get('msg')}") TOKEN_CACHE["value"] = data["tenant_access_token"] TOKEN_CACHE["expire_at"] = time.time() + data["expire"] return TOKEN_CACHE["value"]这个函数在缓存未过期时直接返回旧Token,只有快过期才重新请求。我在实际项目里一直用这个模式,在批量同步多维表格数据时能明显减少认证接口的调用次数。
5. 权限开通期最容易踩的五个坑:每一个我都有真实教训
5.1 “我明明开了权限,为什么接口还是报错”——版本没发布的坑
有朋友写脚本调多维表格接口,明明控制台里权限已经勾上了,请求仍然返回类似no permission的错误。我让他去“版本管理与发布”看,他最新版本状态是“未发布”,线上跑的还是旧配置。勾了权限之后忘了发布,等于钥匙配好了但没有装进门禁卡,门当然不会开。
排查顺序建议固定为:
- 权限管理里确认权限存在;
- 版本管理与发布里确认最新版本已“启用”或“审核通过”;
- 再跑一次接口验证。
5.2 “勾了查看权限却想写数据”——权限粒度没搞清的坑
另一个常见场景:只勾了“查看多维表格”权限,然后直接调用创建记录的接口,读接口一切正常,写接口立刻报403。这不算Bug,是权限粒度不够。
解决方案只有一条:切到“编辑和管理多维表格”权限,重新发布版本。建议一开始就想清楚自己到底要读还是要写,省得来回折腾审核流程。
5.3 App Secret被当成普通配置贴在代码仓库里的坑
App Secret一旦泄露,拿到它的人可以以你的应用身份访问企业数据,而且很难快速识别是谁在用。最危险的做法是把App Secret写进代码文件,再提交到代码托管平台。
正确姿势:
- 代码仓库里只放
FEISHU_APP_SECRET这样的环境变量名; - 本地用环境变量或密钥管理工具保存真实值;
- 如果怀疑泄露,第一时间回到控制台“重置”App Secret。
5.4 测试企业、正式企业、多账号之间来回横跳的坑
有些团队有测试环境和正式环境两个飞书企业,有人在不同环境各建了一个应用,结果复制配置时把测试环境的App ID带到了正式脚本里。看到的现象很魔幻:权限配了、版本也发布了,请求却报应用不存在或凭证校验失败。
解决办法很简单:在环境变量里把应用标识和环境对应起来,名字取得一眼能分辨:
export FEISHU_APP_ID_PROD="cli_production" export FEISHU_APP_ID_STAGING="cli_staging"写脚本时显式区分环境,不要一股脑用同一个变量名。
5.5 应用可见范围是个隐形开关:API和前端一样受它约束
不少人在控制台创建应用时会设置应用可见范围,比如只让某个部门可见。问题在于:接口调用同样受这个范围约束。如果多维表格的创建者不在应用可见范围内,即使你用的是tenant_access_token,API也可能返回无权限。
处理方式:在应用详情页把“可用范围”设置为“全部成员”,或者至少包含要操作表格的那批人。改完同样要重新发布版本,原理见5.1。
6. 自检清单与下一篇预告:确认第一关真正通关
6.1 第一关通关自检表:五项全绿才算完
建议按下面这张表逐项打勾:
| 检查项 | 怎么查 | 通过标准 |
|---|---|---|
| 已创建企业自建应用 | 控制台的“应用列表”能看到 | 应用状态正常,App ID以cli_开头 |
| 多维表格权限已勾选 | 权限管理中搜索“多维表格” | 能看到“编辑和管理”权限 |
| 版本已发布并通过审核 | 版本管理与发布中查看状态 | 最新版本处于启用状态 |
| 能成功获取tenant_access_token | 运行上面的Python脚本 | code=0,token不为空 |
| Secret没有硬编码在代码里 | 全局搜索代码文件 | 找不到App Secret明文 |
前四项都过了,这篇教程的目标就完成了。第五项属于“加分安全项”,建议从一开始就养成好习惯。
6.2 下一站预告:读取多维表格数据的第一步
拿到tenant_access_token之后,下一步就是把它用到真正的业务接口上:读取多维表格里的数据表、字段和记录。那部分会涉及“如何找到表格的App Token和Table ID”“请求头怎么带Authorization”这些细节,我也会把调试过程中常见的几百个字符报错逐条拆开讲。
可以提前想一个问题:飞书多维表格里,一张数据表的唯一标识通常不叫“表格名称”,而是另一串ID。下一篇会专门讲清楚这些ID从哪看、怎么用。
最后再分享一句实际体会:我帮人排查权限问题排查多了之后发现,飞书多维表格的API,真正的门槛不在Python,而在那条权限链路。今天把这张“门禁卡”办明白,后面的事情,基本就是复制粘贴、跑通完事。