调用服务端 API
本文档介绍通过 Python SDK 构造 API 请求、调用开放平台服务端 API 的详细步骤。
步骤一:构建 API Client
通过 SDK 调用飞书开放接口之前,你需要先在代码中创建一个 API Client,用来指定当前使用的应用、日志级别、HTTP 请求超时时间等基本信息。
import lark_oapi as lark
client = lark.Client.builder() \
.app_id("APP_ID") \
.app_secret("APP_SECRET") \
.domain(lark.FEISHU_DOMAIN) \
.timeout(3) \
.app_type(lark.AppType.ISV) \
.app_ticket("xxxx") \
.enable_set_token(False) \
.cache(Cache()) \
.log_level(lark.LogLevel.DEBUG) \
.build()各配置项的具体含义参见下表。
| 配置选项 | 配置方式 | 是否必填 | 描述 |
|---|---|---|---|
| app_id | client.app_id("APP_ID") | 是 | 用于设置应用的 App ID。app_id、app_secret 需要传入真实的应用凭证 App ID 和 App Secret,需登录开发者后台,在应用详情页的 凭证与基础信息 > 应用凭证 区域获取。 |
| app_secret | client.app_secret("APP_SECRET") | 是 | 用于设置应用的 App Secret。 |
| domain | client.domain(lark.FEISHU_DOMAIN) | 否 | 用于设置飞书域名。 - 飞书(默认值): https://open.feishu.cn - Lark:https://open.larksuite.com |
| timeout | client.timeout(3) | 否 | 用于设置客户端超时时间,单位:秒。不传值默认为永不超时。 |
| app_type | client.app_type(lark.AppType.ISV) | 否 | 用于指定应用类型。 - 不传值默认表示企业自建应用 - 传入 lark.AppType.ISV 表示商店应用,且需要在 RequestOption 中配置 tenant_key |
| app_ticket | client.app_ticket("xxxx") | 否 | 当 app_type 指定商店应用时,需要在该参数内传入应用的 app_access_token。获取方式参见商店应用获取 app_access_token。 |
| enable_set_token | client.enable_set_token(False) | 否 | 是否允许手动设置 token。 - False(默认值):不允许 - True:允许,传入该值后需要在 RequestOption 中手动配置 token |
| cache | client.cache(Cache()) | 否 | 用于自定义缓存,默认使用预置的本地缓存。 |
| log_level | client.log_level(lark.LogLevel.DEBUG) | 否 | 用于设置日志级别。枚举值: - lark.LogLevel.CRITICAL:严重错误日志,程序可能中断或崩溃。 - lark.LogLevel.ERROR:错误日志,程序部分功能无法运行。 - lark.LogLevel.WARNING(默认值):潜在问题或警告,一般不阻塞程序运行。 - lark.LogLevel.INFO:程序运行日志,一般用于确认程序是否按预期工作。 - lark.LogLevel.DEBUG:调试日志,一般用于调试时诊断问题。 |
示例配置:
对于自建应用使用以下代码创建 API Client。
pythonimport lark_oapi as lark client = lark.Client.builder() \ .app_id("APP_ID") \ .app_secret("APP_SECRET") \ .build()对于商店应用,需在创建 API Client 时,使用
app_type(lark.AppType.ISV)方法指定 AppType 为商店应用。pythonimport lark_oapi as lark client = lark.Client.builder() \ .app_id("APP_ID") \ .app_secret("APP_SECRET") \ .app_type(lark.AppType.ISV) \ .build()
步骤二:构造 API 请求
在项目内创建 API Client 后,即可通过 Client 调用飞书开放接口。如下图示例,你可前往 API 调试台,直接获取指定服务端 API 相关示例代码。

以通过手机号或邮箱获取用户 ID 接口为例,调用示例如下所示。
# Code generated by Lark OpenAPI.
import lark_oapi as lark
from lark_oapi.api.contact.v3 import *
client = lark.Client.builder() \
.app_id("APP_ID") \
.app_secret("APP_SECRET") \
.log_level(lark.LogLevel.DEBUG) \
.build()
# 构造请求对象
request: BatchGetIdUserRequest = BatchGetIdUserRequest.builder() \
.user_id_type("open_id") \
.request_body(BatchGetIdUserRequestBody.builder()
.emails(["xxxx@bytedance.com"])
.mobiles(["15000000000"])
.build()) \
.build()
# 发起请求
response: BatchGetIdUserResponse = client.contact.v3.user.batch_get_id(request)
# 处理失败返回
if not response.success():
lark.logger.error(
f"client.contact.v3.user.batch_get_id failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}")
# 处理业务结果
lark.logger.info(lark.JSON.marshal(response.data, indent=4))代码片段解析:
导入接口所属的业务资源包。
查阅通过手机号或邮箱获取用户 ID 接口文档可知 HTTP URL 为
https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id,根据/open-apis后的 Path 引入相匹配的包。pythonfrom lark_oapi.api.contact.v3 import *配置 API Client,详细配置说明参考上文 步骤一:配置 API Client 章节。
pythonclient = lark.Client.builder() \ .app_id("APP_ID") \ .app_secret("APP_SECRET") \ .log_level(lark.LogLevel.DEBUG) \ .build()配置调用接口所需传入的请求对象,接口具体参数说明参见通过手机号或邮箱获取用户 ID。
python# 构造请求对象 request: BatchGetIdUserRequest = BatchGetIdUserRequest.builder() \ .user_id_type("open_id") \ .request_body(BatchGetIdUserRequestBody.builder() .emails(["xxxx@bytedance.com"]) .mobiles(["15000000000"]) .build()) \ .build()通过 API client 发起请求。
python# 发起请求 response: BatchGetIdUserResponse = client.contact.v3.user.batch_get_id(request)SDK 内通过 client.业务域.版本号.资源.方法名称 来定位具体的 API 方法。你可前往 API 调试台,在指定 API 的浏览器地址栏获取相应的参数信息,如下图所示。
方式一:查阅指定 API 的示例代码,从代码中直接获取用于构造 API 请求的方法。
方式二:通过指定 API 的浏览器地址栏获取相关参数,以 client.业务域.版本号.资源.方法名称 格式拼接 API 方法。
- 下图中 ① project 代表 业务域
- 下图中 ② version 代表 版本号
- 下图中 ③ resource 代表 资源
- 下图中 ④ apiName 代表 方法名称

如果开发工具支持快捷提示,可以通过下图的方式引用出 SDK 内对应的 API 方法。

更多调用示例参见请求示例。
(可选)步骤三:设置请求选项
在每次发起 API 调用时,你可以设置请求级别的相关参数,例如传递 user_access_token(用户访问凭证)、自定义 headers 等。在代码中需使用 RequestOptions 的 Builder 模式构建请求级别的参数,参数说明如下。
| 配置选项 | 描述 |
|---|---|
| tenant_key | 租户 key,商店应用必须设置该选项。 |
| user_access_token | 用户身份 Token,创建 Client 时 enable_set_token 如果设置为 True,则需要根据接口实际所需选择传入该值。获取方式:获取 user_access_token |
| tenant_access_token | 应用身份 Token,创建 Client 时 enable_set_token 如果设置为 True,则需要根据接口实际所需选择传入该值。获取方式: - 商店应用获取 tenant_access_token - 自建应用获取 tenant_access_token |
| app_access_token | 应用身份短期令牌,创建 Client 时 enable_set_token 如果设置为 True,则需要根据接口实际所需选择传入该值。获取方式: - 商店应用获取 app_access_token - 自建应用获取 app_access_token |
| headers | 自定义请求头,Key:Value 形式。这些请求头会被透传到飞书开放平台服务端。 |
以下提供了创建自定义 headers 的示例代码供参考:
import lark_oapi as lark
from lark_oapi.api.contact.v3 import *
# 创建client
client = lark.Client.builder() \
.enable_set_token(True) \
.log_level(lark.LogLevel.DEBUG) \
.build()
# 构造请求对象
request: BatchGetIdUserRequest = BatchGetIdUserRequest.builder() \
.user_id_type("open_id") \
.request_body(BatchGetIdUserRequestBody.builder()
.emails(["xxxx@bytedance.com"])
.mobiles(["15000000000"])
.build()) \
.build()
# 设置请求选项
headers = {"key1": "value1", "key2": "value2"}
req_opt = lark.RequestOption.builder()\
.user_access_token("u-dqBLyo0Mp7Ar7j2x1d.Qi71gjoR0kgTxUy00050E2zTz")\
.headers(headers)\
.build()
# 发起请求
response: BatchGetIdUserResponse = client.contact.v3.user.batch_get_id(request, req_opt)
# 处理失败返回
if not response.success():
lark.logger.error(
f"client.contact.v3.user.batch_get_id failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}")
# 处理业务结果
lark.logger.info(lark.JSON.marshal(response.data, indent=4))步骤四:运行项目
完成以上步骤后,即可运行项目调用 API,如下图所示通过开发工具运行项目,你也可以根据项目部署情况在命令行内通过 python {.py 项目文件} 命令运行。

如果调用成功,会返回成功状态码以及 API 的响应参数。

如果调用失败,会返回指定的错误码与错误信息。

常见问题
如何快速获取接口对应的示例代码?
飞书开放平台提供了 API 调试台,通过该平台可以快速调试服务端 API,快速获取资源 ID 及生成多语言示例代码的能力,为您节省开发成本。例如,通过 API 调试台调用通过手机号或邮箱获取用户 ID 接口,在调试台成功完成测试后,可通过 示例代码 页面查阅 Python SDK 对应的接口调用代码。

如何调用历史版本 API、API 调试台搜索不到的 API、SDK 内找不到方法的 API ?
可以使用 SDK 提供的原生模式调用 API。以调用通过手机号或邮箱获取用户 ID 接口为例,示例代码如下。
import lark_oapi as lark
# 创建client
client = lark.Client.builder() \
.app_id("APP_ID") \
.app_secret("APP_SECRET") \
.log_level(lark.LogLevel.DEBUG) \
.build()
# 构造请求对象
request: lark.BaseRequest = lark.BaseRequest.builder() \
.http_method(lark.HttpMethod.POST) \
.uri("/open-apis/contact/v3/users/batch_get_id") \
.token_types({lark.AccessTokenType.TENANT}) \
.queries([("user_id_type", "open_id")]) \
.body({"emails": ["xxxx@bytedance.com"], "mobiles": ["15000000000"]}) \
.build()
# 发起请求
response: lark.BaseResponse = client.request(request)
# 处理失败返回
if not response.success():
lark.logger.error(
f"client.request failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}")
# 处理业务结果
lark.logger.info(str(response.raw.content, lark.UTF_8))通过 request: lark.BaseRequest = lark.BaseRequest.builder() 构造请求对象,配置说明如下:
| 配置项 | 说明 |
|---|---|
| lark.BaseRequest.http_method(lark.HttpMethod.POST) | 设置 HTTP Method。格式为 lark.HttpMethod.XXX,例如,POST 请求取值 lark.HttpMethod.POST、GET 请求取值 lark.HttpMethod.GET。 |
| lark.BaseRequest.uri("/open-apis/contact/v3/users/batch_get_id") | 设置 HTTP URL,仅取值域名后的 Path。例如 https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id 实际取值为 /open-apis/contact/v3/users/batch_get_id。 如果接口有路径参数(Path),则需要拼接在 HTTP URL 内。 |
| lark.BaseRequest.token_types( | 设置所用的身份 token。枚举值: - lark.AccessTokenType.TENANT:使用 tenant_access_token - lark.AccessTokenType.USER:使用 user_access_token - lark.AccessTokenType.APP:使用 app_access_token |
| lark.BaseRequest.queries([("user_id_type", "open_id")]) | 如果接口有查询参数(Query),则需要通过该配置项传入。 |
lark.BaseRequest.body({"emails": ["xxxx@example.com"], "mobiles": ["1500000xxxx"]}) | 接口请求体(Body)通过该配置项传入。 |
其他调用示例参见原生调用。
如何准确选择 SDK 内 API 对应的方法?
使用 API Client 调用 API 时,对应的方法建议你借助 API 调试台获取,可通过指定接口的地址栏参数拼接方法,也可以直接参考接口提供的示例代码。以通过手机号或邮箱获取用户 ID 接口为例,获取方式如下图所示。

如何异步调用 API?
在原有 SDK 调用代码中,调用的方法名前面加上一个 a 前缀,即可变成 async/await 模式的异步方法。示例代码如下:
import lark_oapi as lark
from lark_oapi.api.im.v1 import *
# 同步调用版本的「发送消息」
def main():
# 创建client
client = lark.Client.builder() \
.app_id(lark.APP_ID) \
.app_secret(lark.APP_SECRET) \
.log_level(lark.LogLevel.DEBUG) \
.build()
# 构造请求对象
request: CreateMessageRequest = CreateMessageRequest.builder() \
.receive_id_type("open_id") \
.request_body(CreateMessageRequestBody.builder()
.receive_id("ou_7d8a6e6df7621556ce0d21922b676706ccs")
.msg_type("text")
.content("")
.uuid("a0d69e20-1dd1-458b-k525-dfeca4015204")
.build()) \
.build()
# 发起请求
response: CreateMessageResponse = client.im.v1.message.create(request)
# 处理失败返回
if not response.success():
lark.logger.error(
f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}")
return
# 处理业务结果
lark.logger.info(lark.JSON.marshal(response.data, indent=4))
# 异步方式版本的「发送消息」
async def amain():
# 创建client
client = lark.Client.builder() \
.app_id(lark.APP_ID) \
.app_secret(lark.APP_SECRET) \
.log_level(lark.LogLevel.DEBUG) \
.build()
# 构造请求对象
request: CreateMessageRequest = CreateMessageRequest.builder() \
.receive_id_type("open_id") \
.request_body(CreateMessageRequestBody.builder()
.receive_id("ou_7d8a6e6df7621556ce0d21922b676706ccs")
.msg_type("text")
.content("")
.uuid("a0d69e20-1dd1-458b-k525-dfeca4015204")
.build()) \
.build()
# 发起请求
response: CreateMessageResponse = await client.im.v1.message.acreate(request)
# 处理失败返回
if not response.success():
lark.logger.error(
f"client.im.v1.message.acreate failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}")
return
# 处理业务结果
lark.logger.info(lark.JSON.marshal(response.data, indent=4))
if __name__ == "__main__":
asyncio.run(amain()) # 异步方式
# main()