lark-oapi-shortcut


Namelark-oapi-shortcut JSON
Version 2024.1.4 PyPI version JSON
download
home_pagehttps://github.com/straydragon/oapi-sdk-python
SummaryLark OpenAPI SDK for Python
upload_time2024-01-04 05:33:23
maintainerstraydragon
docs_urlNone
authorWenbo Mao
requires_python>=3.7
license
keywords lark openapi
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 飞书开放接口 SDK
为帮助开发者更加便捷地使用飞书开放能力开发应用,简化在接入飞书开放平台时的操作步骤,开放平台提供了统一的服务端 SDK。开发者可使用 SDK,快捷地开发功能,提升开发效率。

## 安装
```shell
pip install lark-oapi -U
```
支持 Python 3.7 及以上

## 简单示例
```python
import lark_oapi as lark

# 创建client
client = lark.Client.builder().app_id("APP_ID").app_secret("APP_SECRET").build()

# 构造请求对象
request = lark.contact.v3.GetUserRequest.builder().user_id("7be5fg9a").build()

# 发起请求
response = client.contact.v3.user.get(request)
```
更多示例可参考:[请求示例](./samples/api)

## API Client
开发者在调用 API 前,需要先创建一个 API Client,然后才可以基于 API Client 发起 API 调用。

### 创建 Client
- 自建应用
```python
import lark_oapi as lark

client = lark.Client.builder() \
    .app_id("APP_ID") \
    .app_secret("APP_SECRET") \
    .build()
```

- 商店应用
```python
import lark_oapi as lark

client = lark.Client.builder() \
    .app_id("APP_ID") \
    .app_secret("APP_SECRET") \
    .app_type(lark.AppType.ISV) \
    .build()
```

### Client 配置项
创建 API Client 时,可以对 API Client 进行一定的配置,比如我们可以在创建 API Client 时设置日志级别、http 请求超时时间等。

```python
import lark_oapi as lark

client = lark.Client.builder() \
    .app_id("APP_ID") \
    .app_secret("APP_SECRET") \
    .domain(lark.FEISHU_DOMAIN) \       # 域名, 默认为 https://open.feishu.cn
    .timeout(3) \                       # 客户端超时时间, 单位秒, 默认永不超时
    .app_type(lark.AppType.ISV) \       # 应用类型, 默认为自建应用; 若设为 ISV 需在 request_option 中配置 tenant_key
    .app_ticket("xxxx") \               # 获取 app_access_token 凭证, app_type = ISV 时需配置
    .enable_set_token(False) \          # 是否允许手动设置 token, 默认不开启; 开启后需在 request_option 中配置 token
    .cache(Cache()) \                   # 自定义缓存, 默认使用预置的本地缓存
    .log_level(lark.LogLevel.DEBUG) \   # 日志级别, 默认为 WARNING
    .build()
```

## API 调用
创建完 API Client 后,我们可以使用 ``client.业务域.版本.资源.方法名称`` 来定位具体的 API 方法,然后对具体的 API 发起调用。

![client_expr](./doc/client_expr.png)

飞书开放平台开放的所有 API
列表,可点击[这里查看](https://open.feishu.cn/document/ukTMukTMukTM/uYTM5UjL2ETO14iNxkTN/server-api-list)

### 基本用法
如下示例,我们通过 client 调用 [通过手机号或邮箱获取用户 ID](https://open.feishu.cn/document/server-docs/contact-v3/user/batch_get_id) 接口。

```python
# 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))
```
更多示例可参考:[请求示例](./samples/api)

### Request 配置项
在每次发起 API 调用时,可以设置请求级别的一些参数,比如传递 userAccessToken, 自定义 headers 等。

```python
import lark_oapi as lark
from lark_oapi.api.contact.v3 import *

# 创建client
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()\
    .tenant_access_token("t-g1047hjTXIZKCBFYWXUCK3D2LJWZYCWYL7USXXXX")\
    .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))
```

如上使用 RequestOptions 的 Builder 模式构建请求级别的参数。如下表格,展示了所有可设置的选项:

<table>
  <thead align=left>
    <tr>
      <th>
        配置选项
      </th>
       <th>
        描述
      </th>
    </tr>
  </thead>
  <tbody align=left valign=top>
    <tr>
      <th>
        <code>tenant_key</code>
      </th>
      <td>租户 key, 商店应用必须设置该选项。</td>
    </tr>
    <tr>
      <th>
        <code>user_access_token</code>
      </th>
      <td>用户 token,创建 Client 时 enable_set_token 需要设置为 True。</td>
    </tr>
    <tr>
      <th>
        <code>tenant_access_token</code>
      </th>
      <td>租户 token,创建 Client 时 enable_set_token 需要设置为 True。</td>
    </tr>
    <tr>
      <th>
        <code>app_access_token</code>
      </th>
      <td>应用 token,创建 Client 时 enable_set_token 需要设置为 True。</td>
    </tr>
    <tr>
      <th>
        <code>headers</code>
      </th>
      <td>自定义请求头,这些请求头会被透传到飞书开放平台服务端。</td
    </tr>
  </tbody>
</table>

### 原生方式调用
部分老版本接口,由于没有元数据信息,所以无法生成对应的 SDK 模型,需要使用原生方式调用。

如下示例,使用 client 原生方式同样调用 [通过手机号或邮箱获取用户 ID](https://open.feishu.cn/document/server-docs/contact-v3/user/batch_get_id) 接口。

```python
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))
```
更多示例可参考:[原生调用](samples/api/raw.py)

## 处理消息事件回调
了解消息订阅相关的知识,可以 [点击这里](https://open.feishu.cn/document/ukTMukTMukTM/uUTNz4SN1MjL1UzM)

获取飞书开放平台开放的所有事件列表,可以 [点击这里](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-list)
### 基本用法
开发者订阅消息事件后,可以使用下面代码,对飞书开放平台推送的消息事件进行处理。

如下示例中使用 flask 启动 httpServer,如使用其他 web 框架,只需处理 http 出入参转换即可。

```python
from flask import Flask

import lark_oapi as lark
from lark_oapi.adapter.flask import *
from lark_oapi.api.im.v1 import *

app = Flask(__name__)


def do_p2_im_message_receive_v1(data: P2ImMessageReceiveV1) -> None:
    print(lark.JSON.marshal(data))


def do_customized_event(data: lark.CustomizedEvent) -> None:
    print(lark.JSON.marshal(data))


handler = lark.EventDispatcherHandler.builder(lark.ENCRYPT_KEY, lark.VERIFICATION_TOKEN, lark.LogLevel.DEBUG) \
    .register_p2_im_message_receive_v1(do_p2_im_message_receive_v1) \
    .register_p1_customized_event("message", do_customized_event) \
    .build()


@app.route("/event", methods=["POST"])
def event():
    resp = handler.do(parse_req())
    return parse_resp(resp)


if __name__ == "__main__":
    app.run(port=7777)
```
其中 EventDispatcherHandler.builder(encrypt_key: str, verification_token: str) 方法参数用于签名验证和消息解密使用, 可在 [开发者后台](https://open.feishu.cn/app?lang=zh-CN) ->「事件订阅」中查看。

![console](doc/console.jpeg)

需要注意的是注册处理器时,比如使用 register_p2_im_message_receive_v1 注册接受消息事件回调时,其中的 P2 为消息协议版本,当前飞书开放平台存在 [两种消息协议](https://open.feishu.cn/document/ukTMukTMukTM/uUTNz4SN1MjL1UzM#8f960a4b) ,分别为 1.0 和 2.0。

如下图开发者在注册消息处理器时,需从 [事件列表](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-list) 中查看自己需要的是哪种协议的事件。

如果是 1.0 的消息协议,则注册处理器时,需要找以 register_p1_xxxx 开头的。如果是 2.0 的消息协议,则注册处理器时,需要找以 register_p2_xxxx 开头的。

若在 SDK 中未找到处理器,可使用 register_p1_customized_event 或 register_p2_customized_event 注册自定义事件。

![event_prot](doc/event_prot.png)

更多示例可参考:[事件回调](samples/event)

## 处理卡片行为回调
关于卡片行为相关的知识,可点击[这里查看](https://open.feishu.cn/document/ukTMukTMukTM/uczM3QjL3MzN04yNzcDN)

### 基本用法
开发者可以使用下面代码处理卡片回调,示例中使用 flask 启动 httpServer,如使用其他 web 框架,只需处理 http 出入参转换即可。

```python
from typing import Any

from flask import Flask

import lark_oapi as lark
from lark_oapi.adapter.flask import *

app = Flask(__name__)


def do_interactive_card(data: lark.Card) -> Any:
    print(lark.JSON.marshal(data))
    content = {
        "header": {
            "title": {
                "tag": "plain_text",
                "content": "更新卡片成功"
            },
            "template": "green"
        },
        "elements": [
            {
                "tag": "div",
                "text": {
                    "tag": "lark_md",
                    "content": "**Success!\n成功啦😄**"
                }
            },
        ]
    }
    return content


handler = lark.CardActionHandler.builder(lark.ENCRYPT_KEY, lark.VERIFICATION_TOKEN, lark.LogLevel.DEBUG) \
    .register(do_interactive_card) \
    .build()


@app.route("/card", methods=["POST"])
def card():
    resp = handler.do(parse_req())
    return parse_resp(resp)


if __name__ == "__main__":
    app.run(port=7777)

```

更多示例可参考:[事件回调](samples/card)

## 扩展示例
我们还基于 SDK 封装了常用的 API 组合调用及业务场景示例,如:
* 消息
  * [发送文件消息](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/im/send_file.py)
  * [发送图片消息](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/im/send_image.py)
* 通讯录
  * [获取部门下所有用户列表](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/contact/list_user_by_department.py)
* 多维表格
  * [创建多维表格同时添加数据表](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/base/create_app_and_tables.py)
* 电子表格
  * [复制粘贴某个范围的单元格数据](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/sheets/copy_and_paste_by_range.py)
  * [下载指定范围单元格的所有素材列表](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/sheets/download_media_by_range.py)
* 教程
  * [机器人自动拉群报警](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/quick_start/robot) ([开发教程](https://open.feishu.cn/document/home/message-development-tutorial/introduction))

更多示例可参考:https://github.com/larksuite/oapi-sdk-python-demo

## License
MIT

## 加入讨论群
[_单击_](https://applink.feishu.cn/client/chat/chatter/add_by_link?link_token=575k28fa-2c12-400a-80c0-2d8924e00d38)或扫码加入讨论群

<img src="doc/qrcode.png" width="200" alt="讨论群">

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/straydragon/oapi-sdk-python",
    "name": "lark-oapi-shortcut",
    "maintainer": "straydragon",
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "straydragonl@foxmail.com",
    "keywords": "Lark,OpenAPI",
    "author": "Wenbo Mao",
    "author_email": "maowenbo@bytedance.com",
    "download_url": "https://files.pythonhosted.org/packages/b4/17/8efc910533c9591ea5a4d76f757ee80e5ee8714d42ed98a5f0643fc1fb5e/lark-oapi-shortcut-2024.1.4.tar.gz",
    "platform": null,
    "description": "# \u98de\u4e66\u5f00\u653e\u63a5\u53e3 SDK\n\u4e3a\u5e2e\u52a9\u5f00\u53d1\u8005\u66f4\u52a0\u4fbf\u6377\u5730\u4f7f\u7528\u98de\u4e66\u5f00\u653e\u80fd\u529b\u5f00\u53d1\u5e94\u7528\uff0c\u7b80\u5316\u5728\u63a5\u5165\u98de\u4e66\u5f00\u653e\u5e73\u53f0\u65f6\u7684\u64cd\u4f5c\u6b65\u9aa4\uff0c\u5f00\u653e\u5e73\u53f0\u63d0\u4f9b\u4e86\u7edf\u4e00\u7684\u670d\u52a1\u7aef SDK\u3002\u5f00\u53d1\u8005\u53ef\u4f7f\u7528 SDK\uff0c\u5feb\u6377\u5730\u5f00\u53d1\u529f\u80fd\uff0c\u63d0\u5347\u5f00\u53d1\u6548\u7387\u3002\n\n## \u5b89\u88c5\n```shell\npip install lark-oapi -U\n```\n\u652f\u6301 Python 3.7 \u53ca\u4ee5\u4e0a\n\n## \u7b80\u5355\u793a\u4f8b\n```python\nimport lark_oapi as lark\n\n# \u521b\u5efaclient\nclient = lark.Client.builder().app_id(\"APP_ID\").app_secret(\"APP_SECRET\").build()\n\n# \u6784\u9020\u8bf7\u6c42\u5bf9\u8c61\nrequest = lark.contact.v3.GetUserRequest.builder().user_id(\"7be5fg9a\").build()\n\n# \u53d1\u8d77\u8bf7\u6c42\nresponse = client.contact.v3.user.get(request)\n```\n\u66f4\u591a\u793a\u4f8b\u53ef\u53c2\u8003\uff1a[\u8bf7\u6c42\u793a\u4f8b](./samples/api)\n\n## API Client\n\u5f00\u53d1\u8005\u5728\u8c03\u7528 API \u524d\uff0c\u9700\u8981\u5148\u521b\u5efa\u4e00\u4e2a API Client\uff0c\u7136\u540e\u624d\u53ef\u4ee5\u57fa\u4e8e API Client \u53d1\u8d77 API \u8c03\u7528\u3002\n\n### \u521b\u5efa Client\n- \u81ea\u5efa\u5e94\u7528\n```python\nimport lark_oapi as lark\n\nclient = lark.Client.builder() \\\n    .app_id(\"APP_ID\") \\\n    .app_secret(\"APP_SECRET\") \\\n    .build()\n```\n\n- \u5546\u5e97\u5e94\u7528\n```python\nimport lark_oapi as lark\n\nclient = lark.Client.builder() \\\n    .app_id(\"APP_ID\") \\\n    .app_secret(\"APP_SECRET\") \\\n    .app_type(lark.AppType.ISV) \\\n    .build()\n```\n\n### Client \u914d\u7f6e\u9879\n\u521b\u5efa API Client \u65f6\uff0c\u53ef\u4ee5\u5bf9 API Client \u8fdb\u884c\u4e00\u5b9a\u7684\u914d\u7f6e\uff0c\u6bd4\u5982\u6211\u4eec\u53ef\u4ee5\u5728\u521b\u5efa API Client \u65f6\u8bbe\u7f6e\u65e5\u5fd7\u7ea7\u522b\u3001http \u8bf7\u6c42\u8d85\u65f6\u65f6\u95f4\u7b49\u3002\n\n```python\nimport lark_oapi as lark\n\nclient = lark.Client.builder() \\\n    .app_id(\"APP_ID\") \\\n    .app_secret(\"APP_SECRET\") \\\n    .domain(lark.FEISHU_DOMAIN) \\       # \u57df\u540d, \u9ed8\u8ba4\u4e3a https://open.feishu.cn\n    .timeout(3) \\                       # \u5ba2\u6237\u7aef\u8d85\u65f6\u65f6\u95f4, \u5355\u4f4d\u79d2, \u9ed8\u8ba4\u6c38\u4e0d\u8d85\u65f6\n    .app_type(lark.AppType.ISV) \\       # \u5e94\u7528\u7c7b\u578b, \u9ed8\u8ba4\u4e3a\u81ea\u5efa\u5e94\u7528; \u82e5\u8bbe\u4e3a ISV \u9700\u5728 request_option \u4e2d\u914d\u7f6e tenant_key\n    .app_ticket(\"xxxx\") \\               # \u83b7\u53d6 app_access_token \u51ed\u8bc1, app_type = ISV \u65f6\u9700\u914d\u7f6e\n    .enable_set_token(False) \\          # \u662f\u5426\u5141\u8bb8\u624b\u52a8\u8bbe\u7f6e token, \u9ed8\u8ba4\u4e0d\u5f00\u542f; \u5f00\u542f\u540e\u9700\u5728 request_option \u4e2d\u914d\u7f6e token\n    .cache(Cache()) \\                   # \u81ea\u5b9a\u4e49\u7f13\u5b58, \u9ed8\u8ba4\u4f7f\u7528\u9884\u7f6e\u7684\u672c\u5730\u7f13\u5b58\n    .log_level(lark.LogLevel.DEBUG) \\   # \u65e5\u5fd7\u7ea7\u522b, \u9ed8\u8ba4\u4e3a WARNING\n    .build()\n```\n\n## API \u8c03\u7528\n\u521b\u5efa\u5b8c API Client \u540e\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 ``client.\u4e1a\u52a1\u57df.\u7248\u672c.\u8d44\u6e90.\u65b9\u6cd5\u540d\u79f0`` \u6765\u5b9a\u4f4d\u5177\u4f53\u7684 API \u65b9\u6cd5\uff0c\u7136\u540e\u5bf9\u5177\u4f53\u7684 API \u53d1\u8d77\u8c03\u7528\u3002\n\n![client_expr](./doc/client_expr.png)\n\n\u98de\u4e66\u5f00\u653e\u5e73\u53f0\u5f00\u653e\u7684\u6240\u6709 API\n\u5217\u8868\uff0c\u53ef\u70b9\u51fb[\u8fd9\u91cc\u67e5\u770b](https://open.feishu.cn/document/ukTMukTMukTM/uYTM5UjL2ETO14iNxkTN/server-api-list)\n\n### \u57fa\u672c\u7528\u6cd5\n\u5982\u4e0b\u793a\u4f8b\uff0c\u6211\u4eec\u901a\u8fc7 client \u8c03\u7528 [\u901a\u8fc7\u624b\u673a\u53f7\u6216\u90ae\u7bb1\u83b7\u53d6\u7528\u6237 ID](https://open.feishu.cn/document/server-docs/contact-v3/user/batch_get_id) \u63a5\u53e3\u3002\n\n```python\n# Code generated by Lark OpenAPI.\n\nimport lark_oapi as lark\nfrom lark_oapi.api.contact.v3 import *\n\n\nclient = lark.Client.builder() \\\n    .app_id(\"APP_ID\") \\\n    .app_secret(\"APP_SECRET\") \\\n    .log_level(lark.LogLevel.DEBUG) \\\n    .build()\n\n# \u6784\u9020\u8bf7\u6c42\u5bf9\u8c61\nrequest: BatchGetIdUserRequest = BatchGetIdUserRequest.builder() \\\n    .user_id_type(\"open_id\") \\\n    .request_body(BatchGetIdUserRequestBody.builder()\n                  .emails([\"xxxx@bytedance.com\"])\n                  .mobiles([\"15000000000\"])\n                  .build()) \\\n    .build()\n\n# \u53d1\u8d77\u8bf7\u6c42\nresponse: BatchGetIdUserResponse = client.contact.v3.user.batch_get_id(request)\n\n# \u5904\u7406\u5931\u8d25\u8fd4\u56de\nif not response.success():\n    lark.logger.error(\n        f\"client.contact.v3.user.batch_get_id failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}\")\n\n# \u5904\u7406\u4e1a\u52a1\u7ed3\u679c\nlark.logger.info(lark.JSON.marshal(response.data, indent=4))\n```\n\u66f4\u591a\u793a\u4f8b\u53ef\u53c2\u8003\uff1a[\u8bf7\u6c42\u793a\u4f8b](./samples/api)\n\n### Request \u914d\u7f6e\u9879\n\u5728\u6bcf\u6b21\u53d1\u8d77 API \u8c03\u7528\u65f6\uff0c\u53ef\u4ee5\u8bbe\u7f6e\u8bf7\u6c42\u7ea7\u522b\u7684\u4e00\u4e9b\u53c2\u6570\uff0c\u6bd4\u5982\u4f20\u9012 userAccessToken, \u81ea\u5b9a\u4e49 headers \u7b49\u3002\n\n```python\nimport lark_oapi as lark\nfrom lark_oapi.api.contact.v3 import *\n\n# \u521b\u5efaclient\nimport lark_oapi as lark\nfrom lark_oapi.api.contact.v3 import *\n\n# \u521b\u5efaclient\nclient = lark.Client.builder() \\\n    .enable_set_token(True) \\\n    .log_level(lark.LogLevel.DEBUG) \\\n    .build()\n\n# \u6784\u9020\u8bf7\u6c42\u5bf9\u8c61\nrequest: BatchGetIdUserRequest = BatchGetIdUserRequest.builder() \\\n    .user_id_type(\"open_id\") \\\n    .request_body(BatchGetIdUserRequestBody.builder()\n                  .emails([\"xxxx@bytedance.com\"])\n                  .mobiles([\"15000000000\"])\n                  .build()) \\\n    .build()\n\n# \u8bbe\u7f6e\u8bf7\u6c42\u9009\u9879\nheaders = {\"key1\": \"value1\", \"key2\": \"value2\"}\nreq_opt = lark.RequestOption.builder()\\\n    .tenant_access_token(\"t-g1047hjTXIZKCBFYWXUCK3D2LJWZYCWYL7USXXXX\")\\\n    .headers(headers)\\\n    .build()\n\n# \u53d1\u8d77\u8bf7\u6c42\nresponse: BatchGetIdUserResponse = client.contact.v3.user.batch_get_id(request, req_opt)\n\n# \u5904\u7406\u5931\u8d25\u8fd4\u56de\nif not response.success():\n    lark.logger.error(\n        f\"client.contact.v3.user.batch_get_id failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}\")\n\n# \u5904\u7406\u4e1a\u52a1\u7ed3\u679c\nlark.logger.info(lark.JSON.marshal(response.data, indent=4))\n```\n\n\u5982\u4e0a\u4f7f\u7528 RequestOptions \u7684 Builder \u6a21\u5f0f\u6784\u5efa\u8bf7\u6c42\u7ea7\u522b\u7684\u53c2\u6570\u3002\u5982\u4e0b\u8868\u683c\uff0c\u5c55\u793a\u4e86\u6240\u6709\u53ef\u8bbe\u7f6e\u7684\u9009\u9879\uff1a\n\n<table>\n  <thead align=left>\n    <tr>\n      <th>\n        \u914d\u7f6e\u9009\u9879\n      </th>\n       <th>\n        \u63cf\u8ff0\n      </th>\n    </tr>\n  </thead>\n  <tbody align=left valign=top>\n    <tr>\n      <th>\n        <code>tenant_key</code>\n      </th>\n      <td>\u79df\u6237 key, \u5546\u5e97\u5e94\u7528\u5fc5\u987b\u8bbe\u7f6e\u8be5\u9009\u9879\u3002</td>\n    </tr>\n    <tr>\n      <th>\n        <code>user_access_token</code>\n      </th>\n      <td>\u7528\u6237 token\uff0c\u521b\u5efa Client \u65f6 enable_set_token \u9700\u8981\u8bbe\u7f6e\u4e3a True\u3002</td>\n    </tr>\n    <tr>\n      <th>\n        <code>tenant_access_token</code>\n      </th>\n      <td>\u79df\u6237 token\uff0c\u521b\u5efa Client \u65f6 enable_set_token \u9700\u8981\u8bbe\u7f6e\u4e3a True\u3002</td>\n    </tr>\n    <tr>\n      <th>\n        <code>app_access_token</code>\n      </th>\n      <td>\u5e94\u7528 token\uff0c\u521b\u5efa Client \u65f6 enable_set_token \u9700\u8981\u8bbe\u7f6e\u4e3a True\u3002</td>\n    </tr>\n    <tr>\n      <th>\n        <code>headers</code>\n      </th>\n      <td>\u81ea\u5b9a\u4e49\u8bf7\u6c42\u5934\uff0c\u8fd9\u4e9b\u8bf7\u6c42\u5934\u4f1a\u88ab\u900f\u4f20\u5230\u98de\u4e66\u5f00\u653e\u5e73\u53f0\u670d\u52a1\u7aef\u3002</td\n    </tr>\n  </tbody>\n</table>\n\n### \u539f\u751f\u65b9\u5f0f\u8c03\u7528\n\u90e8\u5206\u8001\u7248\u672c\u63a5\u53e3\uff0c\u7531\u4e8e\u6ca1\u6709\u5143\u6570\u636e\u4fe1\u606f\uff0c\u6240\u4ee5\u65e0\u6cd5\u751f\u6210\u5bf9\u5e94\u7684 SDK \u6a21\u578b\uff0c\u9700\u8981\u4f7f\u7528\u539f\u751f\u65b9\u5f0f\u8c03\u7528\u3002\n\n\u5982\u4e0b\u793a\u4f8b\uff0c\u4f7f\u7528 client \u539f\u751f\u65b9\u5f0f\u540c\u6837\u8c03\u7528 [\u901a\u8fc7\u624b\u673a\u53f7\u6216\u90ae\u7bb1\u83b7\u53d6\u7528\u6237 ID](https://open.feishu.cn/document/server-docs/contact-v3/user/batch_get_id) \u63a5\u53e3\u3002\n\n```python\nimport lark_oapi as lark\n\n\n# \u521b\u5efaclient\nclient = lark.Client.builder() \\\n    .app_id(\"APP_ID\") \\\n    .app_secret(\"APP_SECRET\") \\\n    .log_level(lark.LogLevel.DEBUG) \\\n    .build()\n\n# \u6784\u9020\u8bf7\u6c42\u5bf9\u8c61\nrequest: lark.BaseRequest = lark.BaseRequest.builder() \\\n    .http_method(lark.HttpMethod.POST) \\\n    .uri(\"/open-apis/contact/v3/users/batch_get_id\") \\\n    .token_types({lark.AccessTokenType.TENANT}) \\\n    .queries([(\"user_id_type\", \"open_id\")]) \\\n    .body({\"emails\": [\"xxxx@bytedance.com\"], \"mobiles\": [\"15000000000\"]}) \\\n    .build()\n\n# \u53d1\u8d77\u8bf7\u6c42\nresponse: lark.BaseResponse = client.request(request)\n\n# \u5904\u7406\u5931\u8d25\u8fd4\u56de\nif not response.success():\n    lark.logger.error(\n        f\"client.request failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}\")\n\n# \u5904\u7406\u4e1a\u52a1\u7ed3\u679c\nlark.logger.info(str(response.raw.content, lark.UTF_8))\n```\n\u66f4\u591a\u793a\u4f8b\u53ef\u53c2\u8003\uff1a[\u539f\u751f\u8c03\u7528](samples/api/raw.py)\n\n## \u5904\u7406\u6d88\u606f\u4e8b\u4ef6\u56de\u8c03\n\u4e86\u89e3\u6d88\u606f\u8ba2\u9605\u76f8\u5173\u7684\u77e5\u8bc6\uff0c\u53ef\u4ee5 [\u70b9\u51fb\u8fd9\u91cc](https://open.feishu.cn/document/ukTMukTMukTM/uUTNz4SN1MjL1UzM)\n\n\u83b7\u53d6\u98de\u4e66\u5f00\u653e\u5e73\u53f0\u5f00\u653e\u7684\u6240\u6709\u4e8b\u4ef6\u5217\u8868\uff0c\u53ef\u4ee5 [\u70b9\u51fb\u8fd9\u91cc](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-list)\n### \u57fa\u672c\u7528\u6cd5\n\u5f00\u53d1\u8005\u8ba2\u9605\u6d88\u606f\u4e8b\u4ef6\u540e\uff0c\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u4ee3\u7801\uff0c\u5bf9\u98de\u4e66\u5f00\u653e\u5e73\u53f0\u63a8\u9001\u7684\u6d88\u606f\u4e8b\u4ef6\u8fdb\u884c\u5904\u7406\u3002\n\n\u5982\u4e0b\u793a\u4f8b\u4e2d\u4f7f\u7528 flask \u542f\u52a8 httpServer\uff0c\u5982\u4f7f\u7528\u5176\u4ed6 web \u6846\u67b6\uff0c\u53ea\u9700\u5904\u7406 http \u51fa\u5165\u53c2\u8f6c\u6362\u5373\u53ef\u3002\n\n```python\nfrom flask import Flask\n\nimport lark_oapi as lark\nfrom lark_oapi.adapter.flask import *\nfrom lark_oapi.api.im.v1 import *\n\napp = Flask(__name__)\n\n\ndef do_p2_im_message_receive_v1(data: P2ImMessageReceiveV1) -> None:\n    print(lark.JSON.marshal(data))\n\n\ndef do_customized_event(data: lark.CustomizedEvent) -> None:\n    print(lark.JSON.marshal(data))\n\n\nhandler = lark.EventDispatcherHandler.builder(lark.ENCRYPT_KEY, lark.VERIFICATION_TOKEN, lark.LogLevel.DEBUG) \\\n    .register_p2_im_message_receive_v1(do_p2_im_message_receive_v1) \\\n    .register_p1_customized_event(\"message\", do_customized_event) \\\n    .build()\n\n\n@app.route(\"/event\", methods=[\"POST\"])\ndef event():\n    resp = handler.do(parse_req())\n    return parse_resp(resp)\n\n\nif __name__ == \"__main__\":\n    app.run(port=7777)\n```\n\u5176\u4e2d EventDispatcherHandler.builder(encrypt_key: str, verification_token: str) \u65b9\u6cd5\u53c2\u6570\u7528\u4e8e\u7b7e\u540d\u9a8c\u8bc1\u548c\u6d88\u606f\u89e3\u5bc6\u4f7f\u7528, \u53ef\u5728 [\u5f00\u53d1\u8005\u540e\u53f0](https://open.feishu.cn/app?lang=zh-CN) ->\u300c\u4e8b\u4ef6\u8ba2\u9605\u300d\u4e2d\u67e5\u770b\u3002\n\n![console](doc/console.jpeg)\n\n\u9700\u8981\u6ce8\u610f\u7684\u662f\u6ce8\u518c\u5904\u7406\u5668\u65f6\uff0c\u6bd4\u5982\u4f7f\u7528 register_p2_im_message_receive_v1 \u6ce8\u518c\u63a5\u53d7\u6d88\u606f\u4e8b\u4ef6\u56de\u8c03\u65f6\uff0c\u5176\u4e2d\u7684 P2 \u4e3a\u6d88\u606f\u534f\u8bae\u7248\u672c\uff0c\u5f53\u524d\u98de\u4e66\u5f00\u653e\u5e73\u53f0\u5b58\u5728 [\u4e24\u79cd\u6d88\u606f\u534f\u8bae](https://open.feishu.cn/document/ukTMukTMukTM/uUTNz4SN1MjL1UzM#8f960a4b) \uff0c\u5206\u522b\u4e3a 1.0 \u548c 2.0\u3002\n\n\u5982\u4e0b\u56fe\u5f00\u53d1\u8005\u5728\u6ce8\u518c\u6d88\u606f\u5904\u7406\u5668\u65f6\uff0c\u9700\u4ece [\u4e8b\u4ef6\u5217\u8868](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-list) \u4e2d\u67e5\u770b\u81ea\u5df1\u9700\u8981\u7684\u662f\u54ea\u79cd\u534f\u8bae\u7684\u4e8b\u4ef6\u3002\n\n\u5982\u679c\u662f 1.0 \u7684\u6d88\u606f\u534f\u8bae\uff0c\u5219\u6ce8\u518c\u5904\u7406\u5668\u65f6\uff0c\u9700\u8981\u627e\u4ee5 register_p1_xxxx \u5f00\u5934\u7684\u3002\u5982\u679c\u662f 2.0 \u7684\u6d88\u606f\u534f\u8bae\uff0c\u5219\u6ce8\u518c\u5904\u7406\u5668\u65f6\uff0c\u9700\u8981\u627e\u4ee5 register_p2_xxxx \u5f00\u5934\u7684\u3002\n\n\u82e5\u5728 SDK \u4e2d\u672a\u627e\u5230\u5904\u7406\u5668\uff0c\u53ef\u4f7f\u7528 register_p1_customized_event \u6216 register_p2_customized_event \u6ce8\u518c\u81ea\u5b9a\u4e49\u4e8b\u4ef6\u3002\n\n![event_prot](doc/event_prot.png)\n\n\u66f4\u591a\u793a\u4f8b\u53ef\u53c2\u8003\uff1a[\u4e8b\u4ef6\u56de\u8c03](samples/event)\n\n## \u5904\u7406\u5361\u7247\u884c\u4e3a\u56de\u8c03\n\u5173\u4e8e\u5361\u7247\u884c\u4e3a\u76f8\u5173\u7684\u77e5\u8bc6\uff0c\u53ef\u70b9\u51fb[\u8fd9\u91cc\u67e5\u770b](https://open.feishu.cn/document/ukTMukTMukTM/uczM3QjL3MzN04yNzcDN)\n\n### \u57fa\u672c\u7528\u6cd5\n\u5f00\u53d1\u8005\u53ef\u4ee5\u4f7f\u7528\u4e0b\u9762\u4ee3\u7801\u5904\u7406\u5361\u7247\u56de\u8c03\uff0c\u793a\u4f8b\u4e2d\u4f7f\u7528 flask \u542f\u52a8 httpServer\uff0c\u5982\u4f7f\u7528\u5176\u4ed6 web \u6846\u67b6\uff0c\u53ea\u9700\u5904\u7406 http \u51fa\u5165\u53c2\u8f6c\u6362\u5373\u53ef\u3002\n\n```python\nfrom typing import Any\n\nfrom flask import Flask\n\nimport lark_oapi as lark\nfrom lark_oapi.adapter.flask import *\n\napp = Flask(__name__)\n\n\ndef do_interactive_card(data: lark.Card) -> Any:\n    print(lark.JSON.marshal(data))\n    content = {\n        \"header\": {\n            \"title\": {\n                \"tag\": \"plain_text\",\n                \"content\": \"\u66f4\u65b0\u5361\u7247\u6210\u529f\"\n            },\n            \"template\": \"green\"\n        },\n        \"elements\": [\n            {\n                \"tag\": \"div\",\n                \"text\": {\n                    \"tag\": \"lark_md\",\n                    \"content\": \"**Success!\\n\u6210\u529f\u5566\ud83d\ude04**\"\n                }\n            },\n        ]\n    }\n    return content\n\n\nhandler = lark.CardActionHandler.builder(lark.ENCRYPT_KEY, lark.VERIFICATION_TOKEN, lark.LogLevel.DEBUG) \\\n    .register(do_interactive_card) \\\n    .build()\n\n\n@app.route(\"/card\", methods=[\"POST\"])\ndef card():\n    resp = handler.do(parse_req())\n    return parse_resp(resp)\n\n\nif __name__ == \"__main__\":\n    app.run(port=7777)\n\n```\n\n\u66f4\u591a\u793a\u4f8b\u53ef\u53c2\u8003\uff1a[\u4e8b\u4ef6\u56de\u8c03](samples/card)\n\n## \u6269\u5c55\u793a\u4f8b\n\u6211\u4eec\u8fd8\u57fa\u4e8e SDK \u5c01\u88c5\u4e86\u5e38\u7528\u7684 API \u7ec4\u5408\u8c03\u7528\u53ca\u4e1a\u52a1\u573a\u666f\u793a\u4f8b\uff0c\u5982\uff1a\n* \u6d88\u606f\n  * [\u53d1\u9001\u6587\u4ef6\u6d88\u606f](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/im/send_file.py)\n  * [\u53d1\u9001\u56fe\u7247\u6d88\u606f](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/im/send_image.py)\n* \u901a\u8baf\u5f55\n  * [\u83b7\u53d6\u90e8\u95e8\u4e0b\u6240\u6709\u7528\u6237\u5217\u8868](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/contact/list_user_by_department.py)\n* \u591a\u7ef4\u8868\u683c\n  * [\u521b\u5efa\u591a\u7ef4\u8868\u683c\u540c\u65f6\u6dfb\u52a0\u6570\u636e\u8868](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/base/create_app_and_tables.py)\n* \u7535\u5b50\u8868\u683c\n  * [\u590d\u5236\u7c98\u8d34\u67d0\u4e2a\u8303\u56f4\u7684\u5355\u5143\u683c\u6570\u636e](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/sheets/copy_and_paste_by_range.py)\n  * [\u4e0b\u8f7d\u6307\u5b9a\u8303\u56f4\u5355\u5143\u683c\u7684\u6240\u6709\u7d20\u6750\u5217\u8868](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/composite_api/sheets/download_media_by_range.py)\n* \u6559\u7a0b\n  * [\u673a\u5668\u4eba\u81ea\u52a8\u62c9\u7fa4\u62a5\u8b66](https://github.com/larksuite/oapi-sdk-python-demo/blob/main/quick_start/robot) ([\u5f00\u53d1\u6559\u7a0b](https://open.feishu.cn/document/home/message-development-tutorial/introduction))\n\n\u66f4\u591a\u793a\u4f8b\u53ef\u53c2\u8003\uff1ahttps://github.com/larksuite/oapi-sdk-python-demo\n\n## License\nMIT\n\n## \u52a0\u5165\u8ba8\u8bba\u7fa4\n[_\u5355\u51fb_](https://applink.feishu.cn/client/chat/chatter/add_by_link?link_token=575k28fa-2c12-400a-80c0-2d8924e00d38)\u6216\u626b\u7801\u52a0\u5165\u8ba8\u8bba\u7fa4\n\n<img src=\"doc/qrcode.png\" width=\"200\" alt=\"\u8ba8\u8bba\u7fa4\">\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Lark OpenAPI SDK for Python",
    "version": "2024.1.4",
    "project_urls": {
        "Homepage": "https://github.com/straydragon/oapi-sdk-python",
        "Source": "https://github.com/straydragon/oapi-sdk-python"
    },
    "split_keywords": [
        "lark",
        "openapi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f64093ecfb904f1b1a7a1ff33f45b15326cb6433eabdf37aca97fde7282350cc",
                "md5": "20b0f3386e2771c0579f08164df24fb2",
                "sha256": "dc989e57dd66be94debb9e0d08e5b29cbc4d28e6960979a499ba72cd05c83da0"
            },
            "downloads": -1,
            "filename": "lark_oapi_shortcut-2024.1.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "20b0f3386e2771c0579f08164df24fb2",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 3677012,
            "upload_time": "2024-01-04T05:33:20",
            "upload_time_iso_8601": "2024-01-04T05:33:20.634078Z",
            "url": "https://files.pythonhosted.org/packages/f6/40/93ecfb904f1b1a7a1ff33f45b15326cb6433eabdf37aca97fde7282350cc/lark_oapi_shortcut-2024.1.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b4178efc910533c9591ea5a4d76f757ee80e5ee8714d42ed98a5f0643fc1fb5e",
                "md5": "1be307ac0e7b581b813f14f4ef2fea4a",
                "sha256": "1e0fe6089b250c417658001a4601feb439dd2b9376fd981458cab848addaaa76"
            },
            "downloads": -1,
            "filename": "lark-oapi-shortcut-2024.1.4.tar.gz",
            "has_sig": false,
            "md5_digest": "1be307ac0e7b581b813f14f4ef2fea4a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 998760,
            "upload_time": "2024-01-04T05:33:23",
            "upload_time_iso_8601": "2024-01-04T05:33:23.261720Z",
            "url": "https://files.pythonhosted.org/packages/b4/17/8efc910533c9591ea5a4d76f757ee80e5ee8714d42ed98a5f0643fc1fb5e/lark-oapi-shortcut-2024.1.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-04 05:33:23",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "straydragon",
    "github_project": "oapi-sdk-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "lark-oapi-shortcut"
}
        
Elapsed time: 0.16537s