From d1c24533102453032dc76bdf65ed45e5c9cf851f Mon Sep 17 00:00:00 2001 From: RockChinQ <1010553892@qq.com> Date: Thu, 21 Dec 2023 16:21:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=90=AF=E5=8A=A8=E6=97=B6=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E4=B8=AD=E5=A4=AE=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=20API=20=E4=BA=A4=E4=BA=92=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 -- main.py | 19 +++++++ pkg/utils/center/__init__.py | 0 pkg/utils/center/apigroup.py | 60 +++++++++++++++++++++ pkg/utils/center/groups/__init__.py | 0 pkg/utils/center/groups/main.py | 48 +++++++++++++++++ pkg/utils/center/groups/plugin.py | 58 +++++++++++++++++++++ pkg/utils/center/groups/usage.py | 81 +++++++++++++++++++++++++++++ pkg/utils/center/v2.py | 33 ++++++++++++ pkg/utils/context.py | 14 +++++ pkg/utils/platform.py | 7 +++ requirements.txt | 1 + 12 files changed, 321 insertions(+), 3 deletions(-) create mode 100644 pkg/utils/center/__init__.py create mode 100644 pkg/utils/center/apigroup.py create mode 100644 pkg/utils/center/groups/__init__.py create mode 100644 pkg/utils/center/groups/main.py create mode 100644 pkg/utils/center/groups/plugin.py create mode 100644 pkg/utils/center/groups/usage.py create mode 100644 pkg/utils/center/v2.py create mode 100644 pkg/utils/platform.py diff --git a/README.md b/README.md index 5c84f766..df8b7991 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,6 @@ Static Badge - 项目主页部署文档功能介绍 | @@ -37,6 +36,4 @@ 插件介绍 回复效果(带有联网插件) - - diff --git a/main.py b/main.py index 155620a5..00af25fb 100644 --- a/main.py +++ b/main.py @@ -163,6 +163,7 @@ async def start_process(first_time_init=False): complete_tips() cfg = pkg.utils.context.get_config_manager().data + # 更新openai库到最新版本 if 'upgrade_dependencies' not in cfg or cfg['upgrade_dependencies']: print("正在更新依赖库,请等待...") @@ -209,6 +210,24 @@ async def start_process(first_time_init=False): break except ValueError: print("请输入数字") + + # 初始化中央服务器 API 交互实例 + from pkg.utils.center import apigroup + from pkg.utils.center import v2 as center_v2 + + center_v2_api = center_v2.V2CenterAPI( + basic_info={ + "host_id": pkg.audit.identifier.identifier['host_id'], + "instance_id": pkg.audit.identifier.identifier['instance_id'], + "semantic_version": pkg.utils.updater.get_current_tag(), + "platform": sys.platform, + }, + runtime_info={ + "admin_qq": cfg['admin_qq'], + "msg_source": cfg['msg_source_adapter'], + } + ) + pkg.utils.context.set_center_v2_api(center_v2_api) import pkg.openai.manager import pkg.database.manager diff --git a/pkg/utils/center/__init__.py b/pkg/utils/center/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pkg/utils/center/apigroup.py b/pkg/utils/center/apigroup.py new file mode 100644 index 00000000..5938fd60 --- /dev/null +++ b/pkg/utils/center/apigroup.py @@ -0,0 +1,60 @@ +import abc +import uuid +import json + +import aiohttp + + +class APIGroup(metaclass=abc.ABCMeta): + """API 组抽象类""" + _basic_info: dict = None + _runtime_info: dict = None + + prefix = None + + def __init__(self, prefix: str): + self.prefix = prefix + + async def do( + self, + method: str, + path: str, + data: dict = None, + params: dict = None, + headers: dict = None, + **kwargs + ): + """执行一个请求""" + url = self.prefix + path + data = json.dumps(data) + headers['Content-Type'] = 'application/json' + async with aiohttp.ClientSession() as session: + async with session.request( + method, + url, + data=data, + params=params, + headers=headers, + **kwargs + ) as resp: + return await resp.json() + + def gen_rid( + self + ): + """生成一个请求 ID""" + return str(uuid.uuid4()) + + def basic_info( + self + ): + """获取基本信息""" + basic_info = APIGroup._basic_info.copy() + basic_info['rid'] = self.gen_rid() + return APIGroup._basic_info + + def runtime_info( + self + ): + """获取运行时信息""" + return APIGroup._runtime_info diff --git a/pkg/utils/center/groups/__init__.py b/pkg/utils/center/groups/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pkg/utils/center/groups/main.py b/pkg/utils/center/groups/main.py new file mode 100644 index 00000000..71bef9b2 --- /dev/null +++ b/pkg/utils/center/groups/main.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +from .. import apigroup + + +class V2MainDataAPI(apigroup.APIGroup): + """主程序相关 数据API""" + + def __init__(self, prefix: str): + super().__init__(prefix+"/main") + + async def post_update_record( + self, + spent_seconds: int, + infer_reason: str, + old_version: str, + new_version: str, + ): + """提交更新记录""" + return await self.do( + "POST", + "/update", + data={ + "basic": self.basic_info(), + "update_info": { + "spent_seconds": spent_seconds, + "infer_reason": infer_reason, + "old_version": old_version, + "new_version": new_version, + } + } + ) + + async def post_announcement_showed( + self, + ids: list[int], + ): + """提交公告已阅""" + return await self.do( + "POST", + "/announcement", + data={ + "basic": self.basic_info(), + "announcement_info": { + "ids": ids, + } + } + ) diff --git a/pkg/utils/center/groups/plugin.py b/pkg/utils/center/groups/plugin.py new file mode 100644 index 00000000..beff8714 --- /dev/null +++ b/pkg/utils/center/groups/plugin.py @@ -0,0 +1,58 @@ +from __future__ import annotations + +from .. import apigroup + + +class V2PluginDataAPI(apigroup.APIGroup): + """插件数据相关 API""" + + def __init__(self, prefix: str): + super().__init__(prefix+"/plugin") + + async def post_install_record( + self, + plugin: dict + ): + """提交插件安装记录""" + return await self.do( + "POST", + "/install", + data={ + "basic": self.basic_info(), + "plugin": plugin, + } + ) + + async def post_remove_record( + self, + plugin: dict + ): + """提交插件卸载记录""" + return await self.do( + "POST", + "/remove", + data={ + "basic": self.basic_info(), + "plugin": plugin, + } + ) + + async def post_update_record( + self, + plugin: dict, + old_version: str, + new_version: str, + ): + """提交插件更新记录""" + return await self.do( + "POST", + "/update", + data={ + "basic": self.basic_info(), + "plugin": plugin, + "update_info": { + "old_version": old_version, + "new_version": new_version, + } + } + ) diff --git a/pkg/utils/center/groups/usage.py b/pkg/utils/center/groups/usage.py new file mode 100644 index 00000000..338b869a --- /dev/null +++ b/pkg/utils/center/groups/usage.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +from .. import apigroup + + +class V2UsageDataAPI(apigroup.APIGroup): + """使用量数据相关 API""" + + def __init__(self, prefix: str): + super().__init__(prefix+"/usage") + + async def post_query_record( + self, + session_type: str, + session_id: str, + query_ability_provider: str, + usage: int, + model_name: str, + response_seconds: int, + retry_times: int, + ): + """提交请求记录""" + return await self.do( + "POST", + "/query", + data={ + "basic": self.basic_info(), + "runtime": self.runtime_info(), + "session_info": { + "type": session_type, + "id": session_id, + }, + "query_info": { + "ability_provider": query_ability_provider, + "usage": usage, + "model_name": model_name, + "response_seconds": response_seconds, + "retry_times": retry_times, + } + } + ) + + async def post_event_record( + self, + plugins: list[dict], + event_name: str, + ): + """提交事件触发记录""" + return await self.do( + "POST", + "/event", + data={ + "basic": self.basic_info(), + "runtime": self.runtime_info(), + "plugins": plugins, + "event_info": { + "name": event_name, + } + } + ) + + async def post_function_record( + self, + plugin: dict, + function_name: str, + function_description: str, + ): + """提交内容函数使用记录""" + return await self.do( + "POST", + "/function", + data={ + "basic": self.basic_info(), + "plugin": plugin, + "function_info": { + "name": function_name, + "description": function_description, + } + } + ) + diff --git a/pkg/utils/center/v2.py b/pkg/utils/center/v2.py new file mode 100644 index 00000000..6cda4093 --- /dev/null +++ b/pkg/utils/center/v2.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from . import apigroup +from .groups import main +from .groups import usage +from .groups import plugin + + +BACKEND_URL = "https://api.qchatgpt.rockchin.top/api/v2" + +class V2CenterAPI: + """中央服务器 v2 API 交互类""" + + main: main.V2MainDataAPI = None + """主 API 组""" + + usage: usage.V2UsageDataAPI = None + """使用量 API 组""" + + plugin: plugin.V2PluginDataAPI = None + """插件 API 组""" + + def __init__(self, basic_info: dict = None, runtime_info: dict = None): + """初始化""" + + print("basic_info:", basic_info) + print("runtime_info:", runtime_info) + apigroup.APIGroup._basic_info = basic_info + apigroup.APIGroup._runtime_info = runtime_info + + self.main = main.V2MainDataAPI(BACKEND_URL) + self.usage = usage.V2UsageDataAPI(BACKEND_URL) + self.plugin = plugin.V2PluginDataAPI(BACKEND_URL) diff --git a/pkg/utils/context.py b/pkg/utils/context.py index e26c702b..e6a2734a 100644 --- a/pkg/utils/context.py +++ b/pkg/utils/context.py @@ -8,6 +8,7 @@ from ..openai import manager as openai_mgr from ..qqbot import manager as qqbot_mgr from ..config import manager as config_mgr from ..plugin import host as plugin_host +from .center import v2 as center_v2 context = { @@ -114,3 +115,16 @@ def get_thread_ctl() -> threadctl.ThreadCtl: t: threadctl.ThreadCtl = context['pool_ctl'] context_lock.release() return t + + +def set_center_v2_api(inst: center_v2.V2CenterAPI): + context_lock.acquire() + context['center_v2_api'] = inst + context_lock.release() + + +def get_center_v2_api() -> center_v2.V2CenterAPI: + context_lock.acquire() + t: center_v2.V2CenterAPI = context['center_v2_api'] + context_lock.release() + return t \ No newline at end of file diff --git a/pkg/utils/platform.py b/pkg/utils/platform.py new file mode 100644 index 00000000..b280b071 --- /dev/null +++ b/pkg/utils/platform.py @@ -0,0 +1,7 @@ +import os +import sys + + +def get_platform() -> str: + """获取当前平台""" + return sys.platform diff --git a/requirements.txt b/requirements.txt index 7047d580..c3e29401 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ nakuru-project-idk CallingGPT tiktoken PyYaml +aiohttp \ No newline at end of file