本文档提供「A/B测试」应用中开放接口的说明。
可用范围包括:
为了保证您和用户的数据安全,开放接口权限默认是关闭的。
在开始使用之前,您需要联系我们开通。(您可以通过服务对接的飞书/微信群或页面右下角的在线客服与我们取得联系)
实验数据的导出需要接入openapi的相关sdk,我们提供了Python SDK和Java SDK,SDK下载地址:
Python SDK下载完成后在shell中执行命令完成安装
# 需要 python 2.7 easy_install rangersdk-0.0.1-py2.7.egg
from rangersdk.client import RangersClient import ujson ak = '{使用AK替换}' sk = '{使用SK替换}' bc = RangersClient(ak, sk) # Get Method Example def test1(): params = {'{key}': '{value}'} # 参数,选填 resp = bc.data_tester('/openapi/v1/164287/details', params=params, method='get') # get请求方法 print(resp.content) # 打印返回结果 res = resp.json() # 将结果转化为json格式 self.assertEqual(200, res['code'], 'err message: {}'.format(res['message'])) # Post Method Example def test2(): params = {'{key}': '{value}'} # 参数,选填 resp = bc.data_tester('/openapi/v1/openapi-test', body=ujson.dumps(params), method='post') # post请求方法 print(resp.content) # 打印返回结果 res = resp.json() # 将结果转化为json格式 self.assertEqual(200, res['code'], 'err message: {}'.format(res['message']))
接口描述:获取实验相关配置的基础信息
请求路径:/openapi/v1/apps/<app_id>/experiment/<experiment_id>/details
请求方式:GET
请求所需参数:
参数 | 类型 | 描述 |
app_id | int | 应用的id |
experiment_id | int | 实验的id |
接口返回值:
参数 | 类型 | 描述 |
code | int | 接口返回状态,200为成功 |
message | string | 接口返回信息,成功时默认为success |
data | object | 接口返回实验信息配置 |
data信息:
参数 | 类型 | 描述 |
id | int | 实验的flight_id |
name | string | 实验名称 |
start_ts | string | 实验开始时间 |
end_ts | string | 实验结束时间 |
owner | string | 实验创建人的user_id |
description | string | 实验描述 |
status | int | 实验状态,0:已结束 1:进行中 2: 待调度 3:测试中 4:草稿中 |
type | string | 实验类型,client:客户端 server:服务端 |
mode | int | 实验模式,1:编程实验 2:多链接实验 3:可视化实验 |
layer | object | 实验所在层相关属性,详见示例描述 |
version_resourse | float | 该实验分配的流量比例 |
versions | list | 实验版本相关属性,详见示例描述 |
metrics | list | 实验指标相关属性,详见示例描述 |
features | object | 实验feature相关属性,详见示例描述 |
filter | string | 用户过滤条件 |
whitelist | list | 用户白名单,详见示例描述 |
接口返回示例:
{ 'code':200 "data": { "id": 3799, # 实验ID "name": "实时指标报告测试", # 实验名称 "start_ts": "2020-07-08 11:39:02", # 实验开始时间 "end_ts": "2021-07-08 11:39:02", # 实验结束时间 "owner": "203870", # 创建者 "description": "", # 实验描述 "status": 1, # 实验状态,0:已结束 1:进行中 2: 待调度 3:测试中 4:草稿中 "type": "client", # 实验类型,client:客户端 server:服务端 "mode": 1, # 实验模式,1:编程实验 2:多链接实验 3:客户端实验 "layer": { # 实验层 "name": "互斥组1", # 互斥层名称 "status": 1, # 互斥层状态,0:已关闭 1:已开启 "description": "LS的测试场景五实验时创建时默认层", # 互斥层描述 "type": "NULL" # 互斥层类型,default: mutex: NULL: }, "version_resource": 1.0, # 流量分配 "versions": [ { "id": 8572, # 版本ID "name": "对照版本", # 版本名称 "type": 0, # 版本类型,0:对照版本 1:实验版本 "config": { # 版本配置 "hello12341": false }, "description": "", # 版本描述 "weight": 30 # 版本权重 }, ... ], "metrics": [ { "id": 10065, # 指标ID "name": "测试指标", # 指标名称 "metric_description": "测试指标描述", # 指标描述 "type": "major", # 指标类型,major:核心 normal:普通 "support_conf": true, # 是否可计算置信度 "offline": false, # 是否离线指标 "dsl": { "queries": [ # 事件详情 { "show_label": "A", "event_type": "origin", # 事件类型 "show_name": "活跃均次(pv/au)", # 事件属性 "event_name": "predefine_pageview", # 事件名称 "filters": [ # 事件过滤条件 { "property_operation": "!=", # 过滤操作符 "property_type": "event_param", # 过滤条件的类型 "property_name": "title", # 过滤条件的名称 "property_values": [ # 过滤条件的值 "这是一个title" ] } ], }, ... ], "event_relation": "A*1" # 混合指标的关系 }, "composed": false # 是否是组合指标 }, ], "features": { "id": -1, # 关联feature的ID,无则-1 "name": "", "key": "" }, "filter": "", # 用户过滤条件 "whitelist": [ # 各实验白名单 { "对照版本": [ { "ssids": ["bbc33321-4352-4b95-91d1-lishanlishanlishan"], # 用户ssid "id": 81, # 白名单ID "is_deleted": false, "name": "李珊", # 创建者 "description": "", # 白名单描述 "tags": [] # 白名单tag }, ] }, ], } 'message':'success' }
接口描述:获取过滤实验报告的参数,使用该接口返回的参数对实验报告与实验留存进行筛选
请求路径:/openapi/v1/apps/<app_id>/filters
请求方式:GET
请求所需参数:
参数 | 类型 | 描述 |
app_id | int | 应用的id |
接口返回值:
参数 | 类型 | 描述 |
code | int | 接口返回状态,200为成功 |
message | string | 接口返回信息,成功时默认为success |
data | object | 接口返回过滤参数信息 |
data信息:
参数 | 类型 | 描述 |
filter_rule | list | 接口返回的过滤参数列表 |
filter_rule信息:
参数 | 类型 | 描述 |
key | string | 过滤参数主键名称 |
label | string | 过滤参数显示的名称,可理解为参数描述 |
type | string | 参数类型 |
preset | int | 是否为默认参数,区别于用户自定义属性 |
values | list | 过滤参数可选值 |
mode | string | 过滤参数的模式,填空:input 枚举:select 混合:multiple |
operators | list | 过滤参数可选操作 |
接口返回示例:
{ "code": 200 "data": { 'filter_rule': [ # 过滤参数 { "key": "referrer", # 过滤参数key "label": "前向地址", # 过滤参数名称 "type": "string", # 参数类型 "preset": 1, # 是否为默认参数 "values": [ { 'value': 'https://www.sogou.com/web?query=xxxx' # value值 'label': 'https://www.sogou.com/web?query=xxxx' # value名称 }, ... ], 'mode': 'multiple', # 过滤参数的模式,填空:input 枚举:select 混合:multiple 'operators': [ # 过滤参数操作方式 { "label": "≠", # 操作符 "value": "ne", # 操作代码 "desc": null, # 操作描述 "mode": "select" # 操作的输入方式,填空:input 枚举:select } ] }, ... ] }, 'message': 'success' }
过滤参数使用方式:
fliters = [ { 'type': 'string', 'op': 'ne', 'key': 'app_channel', 'value': '23' / ['a', 'b'] # 单值/多值筛选 }, ... ]
接口描述:计算并返回实验指标报告
请求路径:/openapi/v1/apps/<app_id>/experiment/<experiment_id>/metrics
请求方式:GET
请求所需参数:
参数 | 类型 | 描述 |
app_id | int | 应用的id |
experiment_id | int | 实验的id |
report_type | string | 报告类型,day:天级 hour:小时级 five_minute:五分钟级 |
start_ts | string | 计算起始时间(时间戳) |
end_ts | string | 计算结束时间(时间戳) |
filters | list | 实验过滤参数,从“获取实验过滤参数”接口处获取 |
接口返回值:
参数 | 类型 | 描述 |
code | int | 接口返回状态,200为成功 |
message | string | 接口返回信息,成功时默认为success |
data | object | 接口返回实验指标信息 |
data信息:
参数 | 类型 | 描述 |
report_type | string | 报告类型,day:天 hour:小时 five_minute:5分钟 |
versions | list | 实验版本信息,详见示例描述 |
metrics | list | 实验相关指标,详见示例描述 |
start_ts | string | 计算起始时间(时间戳) |
end_ts | string | 计算结束时间(时间戳) |
user_data | object | 各版本总进组人数 |
calculation_results | object | 实验指标计算结果,详见示例描述 |
接口返回示例:
{ "code": 200, "data": { "report_type": "day", # 报告类型,day:天 hour:小时 five_minute:5分钟 "versions": [ { "id": 8572, # 版本ID "name": "对照版本", # 版本名称 "config": { "hello12341": false }, "type": 0, # 版本类型,0:对照版本 1:实验版本 "weight": 0 # 版本权重 }, ], "metrics": [ { "id": 10065, "name": "测试指标", "metric_description": "测试指标描述", "type": "major", # 指标类型,major:核心 normal:普通 "support_conf": true, "offline": false, "composed": false }, ... ], "start_ts": 1594179542, # 实验开始时间 "end_ts": 1597247999, # 实验结束时间 "user_data": { "8572": 415248, # 实验总进组人数 "8573": 415261 }, "calculation_results": { "10013": { # 指标ID "8572": { # 实验版本ID,以下类似数字代表该实验相对于另一实验计算得出的值 "m": 1.367, # "p": { "8573": -1 # -1为不存在,小于0.05则置信 }, "change": 0.09640731971910832, # 变化值 "change_rate": { "8573": -0.00053 # 变化率 }, "conf_interval": { "8573": [0,0] # 置信区间 }, "half_interval": { "8573": 0 # 置信区间中点 }, "confidence": { "8573": 3 # 置信情况,1:正向 2:负向 3:不置信 4:新开实验 # 5:数据待更新 6:置信度无法计算 7:没有用户进组 8:已暂停 }, "mde": 0.012623757553642818 # 最小观测差值MDE(minimum detectable effect) }, ... }, ... } }, "message": "success" }
接口描述:计算并返回实验指标报告
请求路径:/openapi/v1/apps/<appid>/experiment/<experiment_id>/retention
请求方式:GET
请求所需参数:
参数 | 类型 | 描述 |
app_id | int | 应用的id |
experiment_id | int | 实验的id |
start_ts | string | 计算起始时间(时间戳) |
end_ts | string | 计算结束时间(时间戳) |
filters | list | 实验过滤参数,从“获取实验过滤参数”接口处获取 |
接口返回值:
参数 | 类型 | 描述 |
code | int | 接口返回状态,200为成功 |
message | string | 接口返回信息,成功时默认为success |
data | object | 接口返回实验留存信息 |
data信息:
参数 | 类型 | 描述 |
start_ts | string | 计算起始时间(时间戳) |
end_ts | string | 计算结束时间(时间戳) |
versions | object | 实验版本信息,详见示例描述 |
confidence_level | int | 置信度 |
calculation_details | object | 实验留存每日数据,详见示例描述 |
calculation_results | object | 实验留存统计数据,详见示例描述 |
接口返回示例:
{ "code": 200 "data": { "available_start_ts": 1594137600, # 实验开始时间 "available_end_ts": 1597247999, # 实验结束时间 "start_ts": 1594656000, # 开始时间 "end_ts": 1597247999, # 结束时间 "versions": [ { "id": 8572, # 版本ID "name": "对照版本", # 版本名称 "config": { "hello12341": false }, "type": 0, # 版本类型 "weight": 0 # 版本权重 }, ], "confidence_level": 90, # 置信度 "calculation_details": { # 留存每日数据 '当日进组用户': { # '8672': [ # 实验ID [ 1597161600, # 日期(时间戳) 5, # 留存率,-1表示不存在,“当日进组用户”时该值等于新进组人数 5.0 # 新进组人数,-1表示不存在 ], ... ], ... }, ... }, 'calculation_results': { # 留存统计数据 "次日留存": { "data": { # 留存率 "8572": 0.0022, "8573": 0.0022 }, "confidence": { # 置信情况,1:正向 2:负向 3:不置信 4:新开实验 # 5:数据待更新 6:置信度无法计算 7:没有用户进组 8:已暂停 "8572": { "8573": 0 }, "8573": { "8572": 0 } }, "p": { # p值 "8572": { "8573": 0.998318 }, "8573": { "8572": 0.998318 } }, "half_interval": { # 置信区间中点 "8572": { "8573": 0.17499327964828007 }, "8573": { "8572": 0.17504366124523396 } }, "change_rate": { # 变化率 "8572": { "8573": -0.000288 }, "8573": { "8572": 0.000288 } }, "conf_interval": { # 置信区间 "8572": { "8573": [ -0.175281, 0.174705 ] }, "8573": { "8572": [ -0.174756, 0.175332 ] } }, "nums": { # 当日总计新进组人数 "8572": 107, "8573": 107 } }, } }, 'message': 'success' }
注意
开放接口所创建的实验,仅管理员可编辑
接口描述:创建实验
请求路径:/openapi/v2/apps/<app_id>/experiments
方法: POST
请求所需参数:
参数名称 | 参数类型 | 是否必填 | 描述 | 备注 |
app_id | int | 是 | 应用的id | |
name | string | 是 | 实验名称 | 不能与已有实验重名,长度50字符 |
mode | int | 是 | 实验类型 | 目前只能是 1 |
description | string | 否 | 实验描述 | 长度1000字符 |
endpoint_type | int | 是 | 实验类型 | 客户端实验:0,服务端实验:1 |
duration | int | 是 | 实验时长 | 单位天,[1, 365],整数 |
major_metric | int | 是 | 核心指标 ID | 目前只支持一个核心指标 |
metrics | list | 是 | 指标ID列表 | 1.必须包含【major_metric】 id,2.必须包含【必看指标】id,3.如果有漏斗类型指标只能有一个 |
versions | list | 是 | 实验版本 | version结构,版本数>=2 |
layer_info | object | 否 | 互斥组 | layer_info结构 |
version结构:
参数名称 | 参数类型 | 是否必填 | 描述 | 备注 |
type | int | 是 | 对照版本/实验版本 | 0:对照版本1:实验版本 |
name | string | 是 | 版本名称 | 长度50字符 |
description | string | 否 | 版本描述 | 长度1000字符 |
weight | float | 否 | 流量分配 | 0.5 最小粒度0.01, 不传均匀分配 |
config | object | 是 | 版本参数不同版本的 key 需要保持一致 | {"key1": "value1","key2": "value2"} |
users | list | 否 | 白名单用户 | [{"ssids": ["009e50ea-fb8e-4bb3-a2a1-4b14ba9ce007","009e50ea-fb8e-4bb3-a2a1-4b14ba9ce006"],"type": "id"}] |
layer_info结构:
参数名称 | 参数类型 | 是否必填 | 描述 | 备注 |
layer_id | int | 是 | 互斥组 ID | 没有传 -1 |
version_resource | float | 是 | 占用流量百分比 | 0.7 小于等于该层剩余流量(available_traffic) |
接口返回值:
参数名称 | 参数类型 | 描述 |
code | int | 接口返回状态,200为成功 |
message | string | 接口返回信息,成功时默认为success |
data | int | 新创建实验ID |
接口请求参数示例:
{ "name":"测试实验2022041901", "mode": 1, "endpoint_type": 1, "duration": 20, "major_metric": 29806, "metrics": [29806], "versions": [ { "type": 0, "name": "实验组2022041901", "config": {"shiyu_key": "hello"} }, { "type": 1, "name": "对照组2022041901", "config": {"shiyu_key": "world"} } ], "layer_info": { "layer_id": -1, "version_resource": 0.7 } }
接口描述:实验开启、结束状态操作
请求路径:
/openapi/v2/apps/<app_id>/experiments/<experiment_id>/launch/
/openapi/v2/apps/<app_id>/experiments/<experiment_id>/stop/
请求方式: PUT
请求所需参数:
参数 | 类型 | 描述 |
app_id | int | 应用的id |
experiment_id | int | 实验ID |
接口描述:获取当前APP下所有指标信息
请求路径: /openapi/v2/apps/<app_id>/metrics
请求方式: GET
接口请求参数:
参数 | 类型 | 描述 |
app_id | int | 应用的id |
keyword | string | 模糊搜索关键字,为空时查询所有 |
need_page | int | 0:不需要分页,page等参数不生效,1:需要分页,page等参数生效 |
page_size | int | 每页显示条数 |
page | int | 当前页,从1开始 |
接口返回信息:
参数 | 类型 | 描述 |
code | int | 接口返回状态,200为成功 |
message | string | 接口返回信息,成功时默认为success |
data | object | 接口返回指标信息和分页信息 |
data信息:
参数 | 类型 | 描述 |
page | object | 分页信息,page结构 |
metrics | list | 指标名称,metric结构 |
page结构:
参数 | 类型 | 描述 |
current_page | int | 当前页 |
total_page | int | 总页数 |
total_items | int | 总条数 |
metric结构:
参数 | 类型 | 描述 |
id | int | 指标ID |
name | string | 指标名称,长度50字符 |
description | string | 指标描述,可能为空 |
type | string | 指标类型 |
is_support_major | boolean | 是否能设置为核心指标 |
is_required | int | 是否为必看指标,0:必看指标,1:非必看指标 |
接口描述:获取当前APP下所有层信息(互斥组)
请求路径: /openapi/v2/apps/<app_id>/layers
请求方式: GET
接口请求参数:
参数 | 类型 | 描述 |
app_id | int | 应用的id |
keyword | string | 模糊搜索关键字,为空时查询所有 |
need_page | int | 0:不需要分页,page等参数不生效,1:需要分页,page等参数生效 |
page_size | int | 每页显示条数 |
page | int | 当前页,从1开始 |
接口返回值:
参数 | 类型 | 描述 |
code | int | 接口返回状态,200为成功 |
message | string | 接口返回信息,成功时默认为success |
data | list | 接口返回互斥组列表 |
data信息:
参数 | 类型 | 描述 |
id | long | 互斥组ID |
name | string | 互斥组名称,长度50字符 |
available_traffic | int | 剩余流量 |
type | string | 互斥组类型,客户端实验只可添加客户端互斥组,服务端实验只可添加服务端互斥组。客户端:client,服务端:server |
HTTP状态码约束如下:
HTTP状态码 | 返回的模块 | 语义 | 解释 | 客户端如何处理 |
200 | 业务模块 | 业务完成了本次请求处理。(不管是成功还是失败) | 在失败的情况下,具体错误原因,通过返回消息体中code进行定义。 | 正常处理 |
302 | 业务模块 | 请求重定向 | 将请求重定向到对应地址 | 重新发出请求 |
403 | 业务模块 | 禁止访问 | 比如接口鉴权失败,token失效,无效access_token,指定用户无操作权限 | 客户端需记录上下文日志,以便查找问题。 |
404 | 网关 | 没有这个接口 | 接口未实现 | 按出错处理,不要重试 |
499 | 网关 | 请求未处理完。 | 按出错处理,可以重试 | |
500 | 业务模块 | 业务在处理过程中,发生了非预期的错误。 | 例如某个异常未捕捉; | 按出错处理,可以重试 |
502/503 | 网关 | 网关在转发请求过程中出错 | 例如到业务模块的连接数过多 | 按出错处理,可以重试 |
返回消息体里的code详细的定义:
错误码 | 含义 |
200 | 成功 |
4001 | 参数校验失败,具体信息在message中给出 |
4002 | 权限校验失败 |
5001 | 接口内部异常 |
5002 | 数据库操作失败 |
5003 | 依赖服务请求失败 |