Skip to main content

A toolkit for buiding blueking API clients.

Project description

蓝鲸云 API 客户端

本项目基于 requests,提供了一种基于配置构建 SDK 的方案。

Features

  • 同时支持网关 API 与组件 API,使用体验一致
  • 支持丰富的请求参数,包括魔法参数 data,requests.request 全部参数(除 data)、路径参数
    • 魔法参数 data,对于 GET/HEAD/OPTIONS 请求,参数将转换为 QueryString,其它请求方法,则转换为 json 格式的 Body
    • 支持从 django settings,Cookies 获取认证数据
  • 支持对 session 进行更新细粒度的控制,支持复用 session 的连接
  • 灵活的响应处理方式
    • 支持校验响应状态码,获取响应的 json 数据
    • 支持获取原始的 requests Response 对象,进行更细粒度的控制
  • 统一采用异常方案,出错时触发异常,如用户认证失败,请求状态码错误,请求网关超频,请求结果非 JSON 等
  • 详细的错误日志,触发异常时,将打印请求的 curl 语句
  • 支持数据懒加载,减小内存消耗
  • 对 IDE 开发友好,SDK 支持常见 IDE 智能提示及补全;
  • 兼容 Python2 及 Python3 的类型补全;

SDK 使用样例

1. 使用 Client

1.1 直接调用 Client,并解析响应

该方式下,SDK 会根据配置自动做请求和响应的转换和解析,隐藏文档已描述的通用细节(如参数位置,响应格式等),用户仅需关注具体字段传递,以减轻使用成本。

from demo.client import Client

# 需提供网关地址 endpoint,环境 stage 默认为 prod
client = Client(stage="prod", endpoint="http://bkapi.example.com/api/test/")
# 根据需求,提供应用认证、用户认证信息
client.update_bkapi_authorization(
    bk_app_code="xxx",
    bk_app_secret="yyy",
    bk_username="admin",
)

# 发起请求,检查 response.raise_for_status(),返回 response.json() 数据
result = client.api.test({"key": "value"})
print(result["ok"])

1.2 直接调用 Client,不解析响应

该方式下,SDK 不会有过多的封装,仅做参数传递,调用 requests 进行请求后返回响应,用户对请求流程有更细粒度的控制。

from demo.client import Client

# 需提供网关地址 endpoint,环境 stage 默认为 prod
client = Client(stage="prod", endpoint="http://bkapi.example.com/api/test/")
# 根据需求,提供应用认证、用户认证信息
client.update_bkapi_authorization(
    bk_app_code="xxx",
    bk_app_secret="yyy",
    bk_username="admin",
)

# 发起请求,但不对响应进行解析,直接返回 requests Response 对象,用户可对响应进行更细粒度的控制
response = client.api.test.request({"key": "value"})
result = response.json()
print(result["ok"])

2. 使用 shortcuts,简化 Client 创建

为降低使用成本,SDK 提供了更简单地创建 Client 的方式:get_client_by_request、get_client_by_username

2.1 使用 get_client_by_request

此方式需提供 django request 对象

get_client_by_request

from demo.shortcuts import get_client_by_request

# 需提供 django request,client 可从 request 中获取当前用户名或从 Cookies 中获取用户登录态
# 并且,支持从 django settings 获取默认的 bk_app_code、bk_app_secret、endpoint,也可通过参数指定
client = get_client_by_request(request)
result = client.api.test({"key": "value"})
print(result["ok])

2.2 使用 get_client_by_username

get_client_by_username

from demo.shortcuts import get_client_by_username

# 支持从 django settings 获取默认的 bk_app_code、bk_app_secret、endpoint,也可通过参数指定
client = get_client_by_username("admin")
result = client.api.test({"key": "value"})
print(result["ok])

3. 复用 session

支持复用 session 连接,提高请求效率

from demo.shortcuts import get_client_by_username

client = get_client_by_username("admin")
with client:
    result = client.api.test({"key": "value"})
    print(result["ok])

SDK 配置说明

SDK 支持通过配置更改一些默认的行为,Django settings 配置优先级高于环境变量。

变量名 描述 类型 格式 默认值 Django 配置 环境变量 别名
BK_APP_CODE 应用代号 string "my_app" 支持 支持 BKPAAS_APP_ID
BK_APP_SECRET 应用密钥 string "my_secret" 支持 支持 BKPAAS_APP_SECRET
DEFAULT_STAGE_MAPPINGS 指定对应网关的默认环境 dict {"my_gateway": "prod"} 支持
BK_API_CLIENT_ENABLE_SSL_VERIFY 是否开启 SSL 证书验证 bool True False 支持
BK_API_AUTHORIZATION_COOKIES_MAPPING 指定 Cookie 和认证参数的映射关系 dict {"key": "cookie"} {"bk_token": "bk_token"} 支持
BK_API_URL_TMPL 网关地址模板,支持 {api_name} 占位符 string "http://{api_name}.example.com" 支持 支持
BK_COMPONENT_API_URL 组件 API 网关地址 string "http://esb.example.com" 支持 支持
DEFAULT_BK_API_VER 默认组件版本号 string "v1" "v2" 支持 支持
BK_API_USE_TEST_ENV 是否使用组件测试环境 bool False False 支持

模型

主要模型定义的类关系请参考 class_diagram.md

Session

requests.Session 的基础之上,增加特有业务逻辑封装:

  • 公共参数设置
  • 超时设置
  • 路径参数设置

同时扩展原有 hooks 机制,为后续进阶需求提供扩展。 session 管理状态及完成每一个接口调用。

Operation

借用 openapi 概念,表示一个路径和方法绑定的操作,相当于网关中的资源及 ESB 中的组件(对应的某个方法),作为配置及调用入口,封装以下属性:

  • 方法
  • 路径
  • 默认配置

Operation 不发起具体的请求,对应的请求会在调用时交给 Manager 完成。

Manager

管理 Session 和 Operation,作为整体的“门面”,可以扩展实现为一个 Client。 其本身不保存状态,而是提供封装,将状态转换成 Session 的基本属性。 其本身也不完成接口调用,而是管理调用流程,处理好请求创建,响应解析和异常处理等步骤。

OperationGroup

Operation 的分组,在 ESB 中,可以用系统名作为分组,而在网关中,即使不区分系统,但为了避免资源和 Client 自身属性的冲突,也使用默认分组管理。

Client

Manager 的子类,管理 OperationGroups 以及其定义的 Operations,针对具体的业务场景中,提供更符合业务流程的封装。

易用性设计

在现有的网关文档中,有较大的一类文档基于程序自动生成,其中虽有描述请求方法,认证方式,调用示例,但因为基于模板生成的原因,其内容较为死板和繁琐。如果由人去机械化地拼接接口的每个配置细节,因为这种方式是反人性的,会有较大的出错概率,由此会带来额外的不必要的咨询和反馈。因此希望 SDK 能够自动帮用户去处理这些机械化的配置,只需要关注核心的调用参数即可完成任务。此外,SDK 本身又可看做某个版本的离线文档,通过 SDK 合理的智能提示和补全,也可以免除用户的查找和排除成本。

接口定义

在接口的设计上,有以下目标:

  • 避免覆盖和重写 __init__ 方法;
  • 使用静态显式的定义方式;
  • 为了减轻内存压力,使用懒加载进行初始化;
  • 没有具体的业务逻辑;

因此接口定义使用类属性 + property 的方式进行:

class Group(OperationGroup):
    test = bind_property(Operation, name="test", method="GET", path="/test/")

如上示例,声明了一个 API 分组 Grouptest 是该分组下注册在网关的一个资源名称,其方法为 GET,资源路径为 /test/

class Client(APIGatewayClient):
    api = bind_property(Group)

上方示例基于 Group 这个 api 分组定义了一个网关客户端,使用 Client 可直接调用这个网关下的所有资源接口。 在接口定义中,bind_property 方法实现了懒加载属性的功能,在调用时自动初始化对应类型,同时基于类型注解实现了泛型,可以帮助 IDE 建立类型系统。

IDE 优化

智能补全

得益于 bind_property 实现的泛型,IDE 可以完成 Client -> Group -> Operation 整个调用链的智能补全。而 Operation 自身的补全方式,完全基于 Operation 定义,仅需维护本项目即可。

接口文档

为了优化 Python3 的调用逻辑,同时兼容 Python2 的使用,SDK 生成定义的同时,也会生成对应的存根文件(.pyi),将接口文档作为 docstring,在 IDE 中引用即可看到文档:

class Group(OperationGroup):
    @property
    def test(self) -> Operation:
        """test api"""

class Client(APIGatewayClient):
    @property
    def api(self) -> Group:
        """api resources"""

存根文件在运行时不会被执行,因此使用等价的 property 描述资源定义,通过 docstring 暴露文档(也是唯一方式)。

进阶使用

统计指标

启用前需安装额外依赖:

pip install bkapi_client_core[monitor]

在项目入口处,执行以下代码启用 prometheus 指标统计的功能:

from bkapi_client_core import prometheus

prometheus.enable()

以上代码只需要执行一次,开启后,sdk 会对每次请求进行指标的统计,暴露到 /metrics 接口,指标如下:

名称 类型 描述 维度
bkapi_requests_duration_seconds Histogram 请求耗时 operation,method
bkapi_requests_body_bytes Histogram 请求体大小 operation,method
bkapi_responses_body_bytes Histogram 响应体大小 operation,method
bkapi_responses_total Counter 响应总数 operation,method,status
bkapi_failures_total Counter 请求失败总数 operation,method,error

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

bkapi_client_core-1.2.0-py2.py3-none-any.whl (31.3 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file bkapi_client_core-1.2.0-py2.py3-none-any.whl.

File metadata

  • Download URL: bkapi_client_core-1.2.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 31.3 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.1 CPython/3.7.4 Linux/5.4.119-1-tlinux4-0010.1

File hashes

Hashes for bkapi_client_core-1.2.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 f18b29e0fc0ee8d5eca33ea1f823f26dc7d7adc2f39670cc45cc2f8452f39630
MD5 05bf4003f1dc34fc2acc2c21e076b32a
BLAKE2b-256 c69b0e76b547a4718f5713a9210dd261d51f32b8c53e2b2ab38bb6286cad61d5

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page