client for openapi service.
Project description
OpenAPI网关服务客户端
功能列表
- 校验token,获取用户信息
- 统一上报操作日志至网关侧
使用指南
安装
pip install ait_openapi
配置网关域名
通过环境变量设置网关域名
OPENAPI_HOST = "https://***.com"
配置校验
from ait_openapi import check_configuration
# 该函数判断是否所有配置ok,只有所有配置ok的情况下,才能调用鉴权计费等接口
config_is_ok = check_configuration()
token校验
from ait_openapi import validate_token, support_model, account_balance_enough
token = "****"
# 根据token,解析用户身份
user_name = validate_token(token)
# 查询当前登陆用户,是否具有指定模型的权限
supported = support_model(token, 'model_name')
# 账户余额判断,支持传入指定判断阈值,服务方可以在每次用户请求前,根据本次预估花费,对用户余额进行校验,若余额不足,则可拒绝请求
balance = account_balance_enough(token, cost=1.0)
如果token无效,抛出AuthorizationException
异常
上报操作日志
为了追踪用户调用中间处理流程,建议在必要处理操作处,进行操作日志记录上报。操作日志记录分别在操作入口处 (操作前)和操作出口处(操作后)进行记录上报。
1. 上报模式
为降低上报操作日志延迟对业务逻辑的影响,上报操作日志采用异步上报模式
async异步上报
日志上报,将采用异步io的方式,上报操作日志,这种方式,可以在单线程中,同时处理多个并发非阻塞IO操作
from ait_openapi import operation_log
@operation_log()
def safety_check(request, *, validate_output: bool):
pass
2. 上报参数更新
操作日志记录,需要传递一些动态参数,需导入预定义的contextvar,在请求起始处进行设置, 请求结束时清空contextvar
from ait_openapi import trace_id_context, caller_id_context, request_url_context
# 整个链路处理前,设置
t_token = trace_id_context.set("*********") # trace_id 当前请求链路唯一标识
c_token = caller_id_context.set("*********") # caller_id 调用方标识, 通过user_info.username获取
r_token = request_url_context.set("*********") # request_url 当前请求url
# #
# 请求处理
# 清空contextvar
trace_id_context.reset(t_token)
caller_id_context.reset(c_token)
request_url_context.reset(r_token)
2.1 使用middleware设置contextvar, 将自动进行token解析,以及上下文设置
如果当前url不需要进行拦截,可以配置exclude_path进行过滤
from ait_openapi.middleware import HttpContextMiddleware, WebSocketHttpContextMiddleware
from fastapi import FastAPI
app = FastAPI()
app.add_middleware(HttpContextMiddleware, exclude_path=["/v1/actuator/health/<pattern>"])
2.2 跨线程上下文复制
由于上下文变量是线程隔离的,因此如果需要在独立于设置上下文变量的其他线程中,进行日志记录操作,需要将上下文变量复制到新的线程中
# 使用contextvars.copy_context(), 复制上下文,并在复制上下文中,执行方法
import contextvars
from functools import partial
from threading import Thread
class ThreadCopyContext(Thread):
def __init__(self, group=None, target=None, name=None,
args=(), kwargs=None, *, daemon=None):
context = contextvars.copy_context()
super().__init__(group, context.run, name,
[partial(target, *args, **kwargs if kwargs else {})],
None, daemon=daemon)
request_url_context = contextvars.ContextVar('request_url', default='empty')
r_token = request_url_context.set('http://localhost:8000')
def run():
print(request_url_context.get())
# 未复制contextvar,新的线程中,上下文变量为默认值空
t = Thread(target=run)
t.start()
t.join()
# > empty
# 复制contextvar,可以获取到复制的上下文变量
t = ThreadCopyContext(target=run)
t.start()
t.join()
# > http://localhost:8000
3. 日志记录配置
日志记录中,op_type字段默认取值为当前方法名称,可通过在装饰器中传入参数进行覆盖。该装饰器可同时用于同步方法以及异步协程的日志上报 为了进行调用计费,如果当前操作日志中的信息,需要用于回调计费,则需要在装饰器中传入is_cost_log=True
from ait_openapi import operation_log
@operation_log(op_type='safety_check', is_cost_log=False)
def safety_check(request, *, validate_output: bool):
pass
@operation_log(is_cost_log=False)
async def safety_check(request, *, validate_output: bool):
pass
4. 直接上报链路日志
4.1 调用submit_log方法
from ait_openapi import submit_log
# construct log
log = ...
submit_log(log)
4.2 http上报
如果在特定场景下,通过装饰器进行链路日志上报不够灵活,您可直接通过调用对应的http 接口上传链路日志 POST接口url:/v1/openapi/report/log
接口参数:
Params
Name | Type | Required | Title | Description |
---|---|---|---|---|
uuid | string | yes | 日志uuid | 每条日志,使用不同uuid标识 |
requestId | string | yes | 链路id | 一次用户请求中,后台多条处理日志,应该使用同一requestId进行串联 |
callerId | string | yes | 调用房标识 | 调用token解析得到的当前调用方标识 |
requestUrl | string | yes | 能力端点 | 用户请求,接口url地址 |
opLogType | string | yes | 操作日志类型 | 如果日志在操作入口记录,则改 |
opType | string | yes | 操作类型 | 日志记录对应的操作名称 |
isCostLog | boolean | yes | 是否计费日志 | 如果为true,且opLogType为out,该条日志将被用户计算用户调用的费用 |
operationStatus | string | yes | 操作状态 | none |
startTimeMillis | integer | yes | 操作起始时间戳 | none |
durationMillis | integer | yes | 操作结束时间戳 | none |
request | object | yes | 操作入参 | none |
response | object | no | 操作出参 | none |
errMsg | string | no | 异常信息 | 如果操作失败,记录失败信息 |
extraInfo | object | no | 其他透传信息 |
Enum
Name | Value | Description |
---|---|---|
opLogType | in | 日志记录为操作入口处记录 |
opLogType | out | 日志记录为操作出口处记录 |
operationStatus | success | 当前操作成功 |
operationStatus | failed | 当前操作失败 |
5. 链路日志查询
get接口地址:/v1/openapi/log/{requestId} 传入链路id,可查询当前链路下的所有日志信息
release log
- 0.0.1.2
- 修复pydantic 2.x版本,BaseModel校验问题
- 0.0.1.3
- 修复account_balance_enough调用异常
- 操作日志中,时间戳记录单位改为毫秒
- README文档,增加日志记录contextvar跨线程复制说明, 操作日志上报http接口介绍
- 0.0.1.4
- 修复log日志记录中,对象无法序列化问题
- 0.0.1.5
- 暴露submit_log,支持直接上报日志
- 0.0.1.8
- 支持不配置openapi_host的情况下,鉴权计费可以正常调通
- 0.0.1.16
- 提供配置检测接口
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file ait_openapi-0.0.1.18.tar.gz
.
File metadata
- Download URL: ait_openapi-0.0.1.18.tar.gz
- Upload date:
- Size: 9.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.10.0 readme-renderer/34.0 requests/2.27.1 requests-toolbelt/1.0.0 urllib3/1.26.18 tqdm/4.64.1 importlib-metadata/4.8.3 keyring/23.4.1 rfc3986/1.5.0 colorama/0.4.5 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0e1420bef7cdd15df62b758d134972ad1c22870edcea5b45c6ff6ce80d66192c |
|
MD5 | d46327b26433b2231f099f3d04b8296a |
|
BLAKE2b-256 | 6dfede283883636378271568b1bf0148523cf4824ca89996089e8b0112cb88b2 |