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 @@
-
项目主页 |
部署文档 |
功能介绍 |
@@ -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