ErisPulse 1.2.9__py3-none-any.whl → 2.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ErisPulse/Core/__init__.py +19 -0
- ErisPulse/Core/adapter.py +619 -0
- ErisPulse/Core/env.py +614 -0
- ErisPulse/{logger.py → Core/logger.py} +1 -118
- ErisPulse/Core/mods.py +226 -0
- ErisPulse/Core/raiserr.py +152 -0
- ErisPulse/Core/server.py +276 -0
- ErisPulse/Core/shellprint.py +165 -0
- ErisPulse/Core/util.py +126 -0
- ErisPulse/__init__.py +654 -243
- ErisPulse/__main__.py +322 -1187
- {erispulse-1.2.9.dist-info → erispulse-2.1.0.dist-info}/METADATA +16 -41
- erispulse-2.1.0.dist-info/RECORD +16 -0
- {erispulse-1.2.9.dist-info → erispulse-2.1.0.dist-info}/entry_points.txt +1 -0
- {erispulse-1.2.9.dist-info → erispulse-2.1.0.dist-info}/licenses/LICENSE +4 -3
- ErisPulse/adapter.py +0 -465
- ErisPulse/db.py +0 -769
- ErisPulse/mods.py +0 -345
- ErisPulse/raiserr.py +0 -141
- ErisPulse/util.py +0 -144
- erispulse-1.2.9.dist-info/RECORD +0 -13
- {erispulse-1.2.9.dist-info → erispulse-2.1.0.dist-info}/WHEEL +0 -0
ErisPulse/__init__.py
CHANGED
|
@@ -1,123 +1,621 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
ErisPulse SDK 主模块
|
|
3
3
|
|
|
4
|
-
提供SDK
|
|
5
|
-
|
|
6
|
-
## 主要功能
|
|
7
|
-
- 构建全局sdk对象
|
|
8
|
-
- 预注册核心错误类型
|
|
9
|
-
- 提供SDK初始化入口
|
|
10
|
-
- 集成各核心模块
|
|
11
|
-
|
|
12
|
-
## API 文档
|
|
13
|
-
### 核心对象:
|
|
14
|
-
- sdk: 全局SDK命名空间对象
|
|
15
|
-
- sdk.init(): SDK初始化入口函数
|
|
16
|
-
|
|
17
|
-
### 预注册错误类型:
|
|
18
|
-
- CaughtExternalError: 外部捕获异常
|
|
19
|
-
- InitError: 初始化错误
|
|
20
|
-
- MissingDependencyError: 缺少依赖错误
|
|
21
|
-
- InvalidDependencyError: 无效依赖错误
|
|
22
|
-
- CycleDependencyError: 循环依赖错误
|
|
23
|
-
- ModuleLoadError: 模块加载错误
|
|
24
|
-
|
|
25
|
-
### 示例用法:
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
from ErisPulse import sdk
|
|
29
|
-
|
|
30
|
-
# 初始化SDK
|
|
31
|
-
sdk.init()
|
|
32
|
-
|
|
33
|
-
# 访问各模块功能
|
|
34
|
-
sdk.logger.info("SDK已初始化")
|
|
35
|
-
```
|
|
4
|
+
提供SDK核心功能模块加载和初始化功能
|
|
36
5
|
|
|
6
|
+
{!--< tips >!--}
|
|
7
|
+
1. 使用前请确保已正确安装所有依赖
|
|
8
|
+
2. 调用sdk.init()进行初始化
|
|
9
|
+
3. 模块加载采用懒加载机制
|
|
10
|
+
{!--< /tips >!--}
|
|
37
11
|
"""
|
|
38
12
|
|
|
39
13
|
import os
|
|
40
14
|
import sys
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
import
|
|
15
|
+
import importlib
|
|
16
|
+
import asyncio
|
|
17
|
+
import toml
|
|
18
|
+
import inspect
|
|
19
|
+
import importlib.metadata
|
|
20
|
+
from typing import Dict, List, Tuple, Optional, Set, Type, Any, Callable
|
|
21
|
+
from pathlib import Path
|
|
45
22
|
|
|
46
23
|
# BaseModules: SDK核心模块
|
|
47
|
-
from . import util
|
|
48
|
-
from .
|
|
49
|
-
from .
|
|
50
|
-
from .
|
|
51
|
-
from .
|
|
52
|
-
from .
|
|
53
|
-
|
|
54
|
-
|
|
24
|
+
from .Core import util
|
|
25
|
+
from .Core import raiserr
|
|
26
|
+
from .Core import logger
|
|
27
|
+
from .Core import env
|
|
28
|
+
from .Core import mods
|
|
29
|
+
from .Core import adapter, AdapterFather, SendDSL
|
|
30
|
+
from .Core import adapter_server
|
|
31
|
+
|
|
32
|
+
# 确保windows下的shell能正确显示颜色
|
|
55
33
|
os.system('')
|
|
56
34
|
|
|
57
|
-
sdk =
|
|
35
|
+
sdk = sys.modules[__name__]
|
|
58
36
|
|
|
59
37
|
BaseModules = {
|
|
60
|
-
"util"
|
|
61
|
-
"logger"
|
|
62
|
-
"raiserr"
|
|
63
|
-
"env"
|
|
64
|
-
"mods"
|
|
65
|
-
"adapter"
|
|
66
|
-
"SendDSL"
|
|
67
|
-
"AdapterFather"
|
|
68
|
-
"BaseAdapter"
|
|
38
|
+
"util": util,
|
|
39
|
+
"logger": logger,
|
|
40
|
+
"raiserr": raiserr,
|
|
41
|
+
"env": env,
|
|
42
|
+
"mods": mods,
|
|
43
|
+
"adapter": adapter,
|
|
44
|
+
"SendDSL": SendDSL,
|
|
45
|
+
"AdapterFather": AdapterFather,
|
|
46
|
+
"BaseAdapter": AdapterFather
|
|
69
47
|
}
|
|
70
48
|
|
|
71
49
|
BaseErrors = {
|
|
72
|
-
"ExternalError"
|
|
73
|
-
"CaughtExternalError"
|
|
74
|
-
"InitError"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"CycleDependencyError" : "依赖循环错误",
|
|
78
|
-
"ModuleLoadError" : "模块加载错误"
|
|
50
|
+
"ExternalError": "外部捕获异常",
|
|
51
|
+
"CaughtExternalError": "捕获的非SDK抛出的异常",
|
|
52
|
+
"InitError": "SDK初始化错误",
|
|
53
|
+
"ModuleLoadError": "模块加载错误",
|
|
54
|
+
"LazyLoadError": "懒加载错误"
|
|
79
55
|
}
|
|
80
56
|
|
|
81
57
|
for module, moduleObj in BaseModules.items():
|
|
82
|
-
|
|
83
|
-
setattr(sdk, module, moduleObj)
|
|
84
|
-
except Exception as e:
|
|
85
|
-
raise e
|
|
58
|
+
setattr(sdk, module, moduleObj)
|
|
86
59
|
|
|
87
60
|
for error, doc in BaseErrors.items():
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
61
|
+
raiserr.register(error, doc=doc)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class LazyModule:
|
|
65
|
+
"""
|
|
66
|
+
懒加载模块包装器
|
|
67
|
+
|
|
68
|
+
当模块第一次被访问时才进行实例化
|
|
69
|
+
|
|
70
|
+
{!--< tips >!--}
|
|
71
|
+
1. 模块的实际实例化会在第一次属性访问时进行
|
|
72
|
+
2. 依赖模块会在被使用时自动初始化
|
|
73
|
+
{!--< /tips >!--}
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def __init__(self, module_name: str, module_class: Type, sdk_ref: Any, module_info: Dict[str, Any]):
|
|
77
|
+
"""
|
|
78
|
+
初始化懒加载包装器
|
|
79
|
+
|
|
80
|
+
:param module_name: 模块名称
|
|
81
|
+
:param module_class: 模块类
|
|
82
|
+
:param sdk_ref: SDK引用
|
|
83
|
+
:param module_info: 模块信息字典
|
|
84
|
+
"""
|
|
85
|
+
self._module_name = module_name
|
|
86
|
+
self._module_class = module_class
|
|
87
|
+
self._sdk_ref = sdk_ref
|
|
88
|
+
self._module_info = module_info
|
|
89
|
+
self._instance = None
|
|
90
|
+
self._initialized = False
|
|
91
|
+
|
|
92
|
+
def _initialize(self):
|
|
93
|
+
"""实际初始化模块"""
|
|
94
|
+
try:
|
|
95
|
+
# 获取类的__init__参数信息
|
|
96
|
+
init_signature = inspect.signature(self._module_class.__init__)
|
|
97
|
+
params = init_signature.parameters
|
|
98
|
+
|
|
99
|
+
# 根据参数决定是否传入sdk
|
|
100
|
+
if 'sdk' in params:
|
|
101
|
+
self._instance = self._module_class(self._sdk_ref)
|
|
102
|
+
else:
|
|
103
|
+
self._instance = self._module_class()
|
|
104
|
+
|
|
105
|
+
setattr(self._instance, "moduleInfo", self._module_info)
|
|
106
|
+
self._initialized = True
|
|
107
|
+
logger.debug(f"模块 {self._module_name} 初始化完成")
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.error(f"模块 {self._module_name} 初始化失败: {e}")
|
|
110
|
+
raise raiserr.LazyLoadError(f"无法初始化模块 {self._module_name}: {e}")
|
|
111
|
+
|
|
112
|
+
def __getattr__(self, name: str) -> Any:
|
|
113
|
+
"""属性访问时触发初始化"""
|
|
114
|
+
if not self._initialized:
|
|
115
|
+
self._initialize()
|
|
116
|
+
return getattr(self._instance, name)
|
|
117
|
+
|
|
118
|
+
def __call__(self, *args, **kwargs) -> Any:
|
|
119
|
+
"""调用时触发初始化"""
|
|
120
|
+
if not self._initialized:
|
|
121
|
+
self._initialize()
|
|
122
|
+
return self._instance(*args, **kwargs)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class AdapterLoader:
|
|
126
|
+
"""
|
|
127
|
+
适配器加载器
|
|
128
|
+
|
|
129
|
+
专门用于从PyPI包加载和初始化适配器
|
|
130
|
+
|
|
131
|
+
{!--< tips >!--}
|
|
132
|
+
1. 适配器必须通过entry-points机制注册到erispulse.adapter组
|
|
133
|
+
2. 适配器类必须继承BaseAdapter
|
|
134
|
+
3. 适配器不适用懒加载
|
|
135
|
+
{!--< /tips >!--}
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
def load() -> Tuple[Dict[str, object], List[str], List[str]]:
|
|
140
|
+
"""
|
|
141
|
+
从PyPI包entry-points加载适配器
|
|
142
|
+
|
|
143
|
+
:return:
|
|
144
|
+
Dict[str, object]: 适配器对象字典 {适配器名: 模块对象}
|
|
145
|
+
List[str]: 启用的适配器名称列表
|
|
146
|
+
List[str]: 停用的适配器名称列表
|
|
147
|
+
|
|
148
|
+
:raises ImportError: 当无法加载适配器时抛出
|
|
149
|
+
"""
|
|
150
|
+
adapter_objs = {}
|
|
151
|
+
enabled_adapters = []
|
|
152
|
+
disabled_adapters = []
|
|
153
|
+
|
|
154
|
+
try:
|
|
155
|
+
# 加载适配器entry-points
|
|
156
|
+
entry_points = importlib.metadata.entry_points()
|
|
157
|
+
if hasattr(entry_points, 'select'):
|
|
158
|
+
adapter_entries = entry_points.select(group='erispulse.adapter')
|
|
159
|
+
else:
|
|
160
|
+
adapter_entries = entry_points.get('erispulse.adapter', [])
|
|
161
|
+
|
|
162
|
+
# 处理适配器
|
|
163
|
+
for entry_point in adapter_entries:
|
|
164
|
+
adapter_objs, enabled_adapters, disabled_adapters = AdapterLoader._process_adapter(
|
|
165
|
+
entry_point, adapter_objs, enabled_adapters, disabled_adapters)
|
|
166
|
+
|
|
167
|
+
except Exception as e:
|
|
168
|
+
logger.error(f"加载适配器entry-points失败: {e}")
|
|
169
|
+
raise ImportError(f"无法加载适配器: {e}")
|
|
170
|
+
|
|
171
|
+
return adapter_objs, enabled_adapters, disabled_adapters
|
|
172
|
+
|
|
173
|
+
@staticmethod
|
|
174
|
+
def _process_adapter(
|
|
175
|
+
entry_point: Any,
|
|
176
|
+
adapter_objs: Dict[str, object],
|
|
177
|
+
enabled_adapters: List[str],
|
|
178
|
+
disabled_adapters: List[str]
|
|
179
|
+
) -> Tuple[Dict[str, object], List[str], List[str]]:
|
|
180
|
+
"""
|
|
181
|
+
{!--< internal-use >!--}
|
|
182
|
+
处理单个适配器entry-point
|
|
183
|
+
|
|
184
|
+
:param entry_point: entry-point对象
|
|
185
|
+
:param adapter_objs: 适配器对象字典
|
|
186
|
+
:param enabled_adapters: 启用的适配器列表
|
|
187
|
+
:param disabled_adapters: 停用的适配器列表
|
|
188
|
+
|
|
189
|
+
:return:
|
|
190
|
+
Dict[str, object]: 更新后的适配器对象字典
|
|
191
|
+
List[str]: 更新后的启用适配器列表
|
|
192
|
+
List[str]: 更新后的禁用适配器列表
|
|
193
|
+
|
|
194
|
+
:raises ImportError: 当适配器加载失败时抛出
|
|
195
|
+
"""
|
|
196
|
+
try:
|
|
197
|
+
loaded_obj = entry_point.load()
|
|
198
|
+
adapter_obj = sys.modules[loaded_obj.__module__]
|
|
199
|
+
dist = importlib.metadata.distribution(entry_point.dist.name)
|
|
200
|
+
|
|
201
|
+
# 创建adapterInfo
|
|
202
|
+
adapter_info = {
|
|
203
|
+
"meta": {
|
|
204
|
+
"name": entry_point.name,
|
|
205
|
+
"version": getattr(adapter_obj, "__version__", dist.version if dist else "1.0.0"),
|
|
206
|
+
"description": getattr(adapter_obj, "__description__", ""),
|
|
207
|
+
"author": getattr(adapter_obj, "__author__", ""),
|
|
208
|
+
"license": getattr(adapter_obj, "__license__", ""),
|
|
209
|
+
"package": entry_point.dist.name
|
|
210
|
+
},
|
|
211
|
+
"adapter_class": loaded_obj
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# 检查是否已经加载过这个适配器类
|
|
215
|
+
existing_instance = None
|
|
216
|
+
for existing_adapter in adapter_objs.values():
|
|
217
|
+
if hasattr(existing_adapter, 'adapterInfo'):
|
|
218
|
+
for existing_adapter_info in existing_adapter.adapterInfo.values():
|
|
219
|
+
if isinstance(existing_adapter_info, dict) and existing_adapter_info["adapter_class"] == loaded_obj:
|
|
220
|
+
existing_instance = existing_adapter_info["adapter_class"]
|
|
221
|
+
break
|
|
222
|
+
|
|
223
|
+
# 如果已经存在实例,则复用
|
|
224
|
+
if existing_instance is not None:
|
|
225
|
+
adapter_info["adapter_class"] = existing_instance
|
|
226
|
+
|
|
227
|
+
if not hasattr(adapter_obj, 'adapterInfo'):
|
|
228
|
+
adapter_obj.adapterInfo = {}
|
|
229
|
+
|
|
230
|
+
adapter_obj.adapterInfo[entry_point.name] = adapter_info
|
|
231
|
+
|
|
232
|
+
# 检查适配器状态
|
|
233
|
+
meta_name = entry_point.name
|
|
234
|
+
stored_info = mods.get_module(meta_name) or {
|
|
235
|
+
"status": True,
|
|
236
|
+
"info": adapter_info
|
|
237
|
+
}
|
|
238
|
+
mods.set_module(meta_name, stored_info)
|
|
239
|
+
|
|
240
|
+
if not stored_info.get('status', True):
|
|
241
|
+
disabled_adapters.append(meta_name)
|
|
242
|
+
logger.warning(f"适配器 {meta_name} 已禁用,跳过加载")
|
|
243
|
+
return adapter_objs, enabled_adapters, disabled_adapters
|
|
244
|
+
|
|
245
|
+
adapter_objs[meta_name] = adapter_obj
|
|
246
|
+
enabled_adapters.append(meta_name)
|
|
247
|
+
logger.debug(f"从PyPI包加载适配器: {meta_name}")
|
|
248
|
+
|
|
249
|
+
except Exception as e:
|
|
250
|
+
logger.warning(f"从entry-point加载适配器 {entry_point.name} 失败: {e}")
|
|
251
|
+
raise ImportError(f"无法加载适配器 {entry_point.name}: {e}")
|
|
252
|
+
|
|
253
|
+
return adapter_objs, enabled_adapters, disabled_adapters
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class ModuleLoader:
|
|
257
|
+
"""
|
|
258
|
+
模块加载器
|
|
259
|
+
|
|
260
|
+
专门用于从PyPI包加载和初始化普通模块
|
|
261
|
+
|
|
262
|
+
{!--< tips >!--}
|
|
263
|
+
1. 模块必须通过entry-points机制注册到erispulse.module组
|
|
264
|
+
2. 模块类名应与entry-point名称一致
|
|
265
|
+
{!--< /tips >!--}
|
|
266
|
+
"""
|
|
267
|
+
|
|
268
|
+
@staticmethod
|
|
269
|
+
def load() -> Tuple[Dict[str, object], List[str], List[str]]:
|
|
270
|
+
"""
|
|
271
|
+
从PyPI包entry-points加载模块
|
|
272
|
+
|
|
273
|
+
:return:
|
|
274
|
+
Dict[str, object]: 模块对象字典 {模块名: 模块对象}
|
|
275
|
+
List[str]: 启用的模块名称列表
|
|
276
|
+
List[str]: 停用的模块名称列表
|
|
277
|
+
|
|
278
|
+
:raises ImportError: 当无法加载模块时抛出
|
|
279
|
+
"""
|
|
280
|
+
module_objs = {}
|
|
281
|
+
enabled_modules = []
|
|
282
|
+
disabled_modules = []
|
|
283
|
+
|
|
284
|
+
try:
|
|
285
|
+
# 加载模块entry-points
|
|
286
|
+
entry_points = importlib.metadata.entry_points()
|
|
287
|
+
if hasattr(entry_points, 'select'):
|
|
288
|
+
module_entries = entry_points.select(group='erispulse.module')
|
|
289
|
+
else:
|
|
290
|
+
module_entries = entry_points.get('erispulse.module', [])
|
|
291
|
+
|
|
292
|
+
# 处理模块
|
|
293
|
+
for entry_point in module_entries:
|
|
294
|
+
module_objs, enabled_modules, disabled_modules = ModuleLoader._process_module(
|
|
295
|
+
entry_point, module_objs, enabled_modules, disabled_modules)
|
|
296
|
+
|
|
297
|
+
except Exception as e:
|
|
298
|
+
logger.error(f"加载模块entry-points失败: {e}")
|
|
299
|
+
raise ImportError(f"无法加载模块: {e}")
|
|
300
|
+
|
|
301
|
+
return module_objs, enabled_modules, disabled_modules
|
|
302
|
+
|
|
303
|
+
@staticmethod
|
|
304
|
+
def _process_module(
|
|
305
|
+
entry_point: Any,
|
|
306
|
+
module_objs: Dict[str, object],
|
|
307
|
+
enabled_modules: List[str],
|
|
308
|
+
disabled_modules: List[str]
|
|
309
|
+
) -> Tuple[Dict[str, object], List[str], List[str]]:
|
|
310
|
+
"""
|
|
311
|
+
{!--< internal-use >!--}
|
|
312
|
+
处理单个模块entry-point
|
|
313
|
+
|
|
314
|
+
:param entry_point: entry-point对象
|
|
315
|
+
:param module_objs: 模块对象字典
|
|
316
|
+
:param enabled_modules: 启用的模块列表
|
|
317
|
+
:param disabled_modules: 停用的模块列表
|
|
318
|
+
|
|
319
|
+
:return:
|
|
320
|
+
Dict[str, object]: 更新后的模块对象字典
|
|
321
|
+
List[str]: 更新后的启用模块列表
|
|
322
|
+
List[str]: 更新后的禁用模块列表
|
|
323
|
+
|
|
324
|
+
:raises ImportError: 当模块加载失败时抛出
|
|
325
|
+
"""
|
|
326
|
+
try:
|
|
327
|
+
loaded_obj = entry_point.load()
|
|
328
|
+
module_obj = sys.modules[loaded_obj.__module__]
|
|
329
|
+
dist = importlib.metadata.distribution(entry_point.dist.name)
|
|
330
|
+
|
|
331
|
+
# 从pyproject.toml读取加载策略
|
|
332
|
+
lazy_load = ModuleLoader._should_lazy_load(dist)
|
|
333
|
+
|
|
334
|
+
# 创建moduleInfo
|
|
335
|
+
module_info = {
|
|
336
|
+
"meta": {
|
|
337
|
+
"name": entry_point.name,
|
|
338
|
+
"version": getattr(module_obj, "__version__", dist.version if dist else "1.0.0"),
|
|
339
|
+
"description": getattr(module_obj, "__description__", ""),
|
|
340
|
+
"author": getattr(module_obj, "__author__", ""),
|
|
341
|
+
"license": getattr(module_obj, "__license__", ""),
|
|
342
|
+
"package": entry_point.dist.name,
|
|
343
|
+
"lazy_load": lazy_load
|
|
344
|
+
},
|
|
345
|
+
"module_class": loaded_obj
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
module_obj.moduleInfo = module_info
|
|
349
|
+
|
|
350
|
+
# 检查模块状态
|
|
351
|
+
meta_name = entry_point.name
|
|
352
|
+
stored_info = mods.get_module(meta_name) or {
|
|
353
|
+
"status": True,
|
|
354
|
+
"info": module_info
|
|
355
|
+
}
|
|
356
|
+
mods.set_module(meta_name, stored_info)
|
|
357
|
+
|
|
358
|
+
if not stored_info.get('status', True):
|
|
359
|
+
disabled_modules.append(meta_name)
|
|
360
|
+
logger.warning(f"模块 {meta_name} 已禁用,跳过加载")
|
|
361
|
+
return module_objs, enabled_modules, disabled_modules
|
|
362
|
+
|
|
363
|
+
module_objs[meta_name] = module_obj
|
|
364
|
+
enabled_modules.append(meta_name)
|
|
365
|
+
logger.debug(f"从PyPI包加载模块: {meta_name}")
|
|
366
|
+
|
|
367
|
+
except Exception as e:
|
|
368
|
+
logger.warning(f"从entry-point加载模块 {entry_point.name} 失败: {e}")
|
|
369
|
+
raise ImportError(f"无法加载模块 {entry_point.name}: {e}")
|
|
370
|
+
|
|
371
|
+
return module_objs, enabled_modules, disabled_modules
|
|
372
|
+
|
|
373
|
+
@staticmethod
|
|
374
|
+
def _should_lazy_load(module_class: Type) -> bool:
|
|
375
|
+
"""
|
|
376
|
+
检查模块是否应该懒加载
|
|
377
|
+
|
|
378
|
+
:param module_class: 模块类
|
|
379
|
+
:return: bool: 如果返回 False,则立即加载;否则懒加载
|
|
380
|
+
"""
|
|
381
|
+
# 检查模块是否定义了 should_eager_load() 方法
|
|
382
|
+
if hasattr(module_class, "should_eager_load"):
|
|
383
|
+
try:
|
|
384
|
+
# 调用静态方法,如果返回 True,则禁用懒加载(立即加载)
|
|
385
|
+
return not module_class.should_eager_load()
|
|
386
|
+
except Exception as e:
|
|
387
|
+
logger.warning(f"调用模块 {module_class.__name__} 的 should_eager_load() 失败: {e}")
|
|
388
|
+
|
|
389
|
+
# 默认启用懒加载
|
|
390
|
+
return True
|
|
391
|
+
|
|
392
|
+
class ModuleInitializer:
|
|
393
|
+
"""
|
|
394
|
+
模块初始化器
|
|
395
|
+
|
|
396
|
+
负责协调适配器和模块的初始化流程
|
|
397
|
+
|
|
398
|
+
{!--< tips >!--}
|
|
399
|
+
1. 初始化顺序:适配器 → 模块
|
|
400
|
+
2. 模块初始化采用懒加载机制
|
|
401
|
+
{!--< /tips >!--}
|
|
402
|
+
"""
|
|
403
|
+
|
|
404
|
+
@staticmethod
|
|
405
|
+
def init() -> bool:
|
|
406
|
+
"""
|
|
407
|
+
初始化所有模块和适配器
|
|
408
|
+
|
|
409
|
+
执行步骤:
|
|
410
|
+
1. 从PyPI包加载适配器
|
|
411
|
+
2. 从PyPI包加载模块
|
|
412
|
+
3. 预记录所有模块信息
|
|
413
|
+
4. 注册适配器
|
|
414
|
+
5. 初始化各模块
|
|
415
|
+
|
|
416
|
+
:return: bool: 初始化是否成功
|
|
417
|
+
"""
|
|
418
|
+
logger.info("[Init] SDK 正在初始化...")
|
|
419
|
+
|
|
420
|
+
try:
|
|
421
|
+
# 1. 先加载适配器
|
|
422
|
+
adapter_objs, enabled_adapters, disabled_adapters = AdapterLoader.load()
|
|
423
|
+
logger.info(f"[Init] 加载了 {len(enabled_adapters)} 个适配器, {len(disabled_adapters)} 个适配器被禁用")
|
|
424
|
+
|
|
425
|
+
# 2. 再加载模块
|
|
426
|
+
module_objs, enabled_modules, disabled_modules = ModuleLoader.load()
|
|
427
|
+
logger.info(f"[Init] 加载了 {len(enabled_modules)} 个模块, {len(disabled_modules)} 个模块被禁用")
|
|
428
|
+
|
|
429
|
+
if os.path.join(os.path.dirname(__file__), "modules"):
|
|
430
|
+
logger.warning("[Warning] 你的项目使用了已经弃用的模块加载方式, 请尽快使用 PyPI 模块加载方式代替")
|
|
431
|
+
|
|
432
|
+
if not enabled_modules and not enabled_adapters:
|
|
433
|
+
logger.warning("[Init] 没有找到可用的模块和适配器")
|
|
434
|
+
return True
|
|
435
|
+
|
|
436
|
+
# 3. 预记录所有模块信息到SDK属性中
|
|
437
|
+
logger.debug("[Init] 正在预记录模块信息...")
|
|
438
|
+
ModuleInitializer._pre_register_modules(enabled_modules, module_objs)
|
|
439
|
+
|
|
440
|
+
# 4. 注册适配器
|
|
441
|
+
logger.debug("[Init] 正在注册适配器...")
|
|
442
|
+
if not ModuleInitializer._register_adapters(enabled_adapters, adapter_objs):
|
|
443
|
+
return False
|
|
444
|
+
|
|
445
|
+
# 5. 初始化模块
|
|
446
|
+
logger.debug("[Init] 正在初始化模块...")
|
|
447
|
+
success = ModuleInitializer._initialize_modules(enabled_modules, module_objs)
|
|
448
|
+
logger.info(f"[Init] SDK初始化{'成功' if success else '失败'}")
|
|
449
|
+
return success
|
|
450
|
+
|
|
451
|
+
except Exception as e:
|
|
452
|
+
logger.critical(f"SDK初始化严重错误: {e}")
|
|
453
|
+
raiserr.InitError(f"sdk初始化失败: {e}", exit=True)
|
|
454
|
+
return False
|
|
455
|
+
|
|
456
|
+
@staticmethod
|
|
457
|
+
def _pre_register_modules(modules: List[str], module_objs: Dict[str, Any]) -> None:
|
|
458
|
+
"""
|
|
459
|
+
预记录所有模块信息到SDK属性中
|
|
460
|
+
|
|
461
|
+
确保所有模块在初始化前都已在SDK中注册
|
|
462
|
+
"""
|
|
463
|
+
for module_name in modules:
|
|
464
|
+
module_obj = module_objs[module_name]
|
|
465
|
+
meta_name = module_obj.moduleInfo["meta"]["name"]
|
|
466
|
+
|
|
467
|
+
# 即使模块是懒加载的,也先在SDK中创建占位符
|
|
468
|
+
if not hasattr(sdk, meta_name):
|
|
469
|
+
setattr(sdk, meta_name, None)
|
|
470
|
+
logger.debug(f"预注册模块: {meta_name}")
|
|
471
|
+
|
|
472
|
+
@staticmethod
|
|
473
|
+
def _register_adapters(adapters: List[str], adapter_objs: Dict[str, Any]) -> bool:
|
|
474
|
+
"""
|
|
475
|
+
{!--< internal-use >!--}
|
|
476
|
+
注册适配器
|
|
477
|
+
|
|
478
|
+
:param adapters: 适配器名称列表
|
|
479
|
+
:param adapter_objs: 适配器对象字典
|
|
480
|
+
|
|
481
|
+
:return: bool: 适配器注册是否成功
|
|
482
|
+
"""
|
|
483
|
+
success = True
|
|
484
|
+
# 存储平台名到适配器类的映射
|
|
485
|
+
platform_to_adapter = {}
|
|
486
|
+
# 存储已注册的适配器类到实例的映射
|
|
487
|
+
registered_classes = {}
|
|
488
|
+
|
|
489
|
+
for adapter_name in adapters:
|
|
490
|
+
adapter_obj = adapter_objs[adapter_name]
|
|
491
|
+
|
|
492
|
+
try:
|
|
493
|
+
if hasattr(adapter_obj, "adapterInfo") and isinstance(adapter_obj.adapterInfo, dict):
|
|
494
|
+
for platform, adapter_info in adapter_obj.adapterInfo.items():
|
|
495
|
+
# 如果这个平台已经注册过,跳过
|
|
496
|
+
if platform in platform_to_adapter:
|
|
497
|
+
continue
|
|
498
|
+
|
|
499
|
+
adapter_class = adapter_info["adapter_class"]
|
|
500
|
+
|
|
501
|
+
# 检查是否已经注册过这个适配器类
|
|
502
|
+
if adapter_class in registered_classes:
|
|
503
|
+
# 获取已注册的实例
|
|
504
|
+
existing_instance = registered_classes[adapter_class]
|
|
505
|
+
# 将新平台名指向已有实例
|
|
506
|
+
sdk.adapter._adapters[platform] = existing_instance
|
|
507
|
+
sdk.adapter._platform_to_instance[platform] = existing_instance
|
|
508
|
+
else:
|
|
509
|
+
# 注册新适配器
|
|
510
|
+
sdk.adapter.register(platform, adapter_class)
|
|
511
|
+
# 记录已注册的类和实例
|
|
512
|
+
registered_classes[adapter_class] = sdk.adapter._adapters[platform]
|
|
513
|
+
|
|
514
|
+
# 记录平台到适配器的映射
|
|
515
|
+
platform_to_adapter[platform] = adapter_class
|
|
516
|
+
logger.info(f"注册适配器: {platform}")
|
|
517
|
+
except Exception as e:
|
|
518
|
+
logger.error(f"适配器 {adapter_name} 注册失败: {e}")
|
|
519
|
+
success = False
|
|
520
|
+
return success
|
|
521
|
+
|
|
522
|
+
@staticmethod
|
|
523
|
+
def _initialize_modules(modules: List[str], module_objs: Dict[str, Any]) -> bool:
|
|
524
|
+
"""
|
|
525
|
+
{!--< internal-use >!--}
|
|
526
|
+
初始化模块
|
|
527
|
+
|
|
528
|
+
:param modules: 模块名称列表
|
|
529
|
+
:param module_objs: 模块对象字典
|
|
530
|
+
|
|
531
|
+
:return: bool: 模块初始化是否成功
|
|
532
|
+
"""
|
|
533
|
+
success = True
|
|
534
|
+
|
|
535
|
+
try:
|
|
536
|
+
entry_points = importlib.metadata.entry_points()
|
|
537
|
+
if hasattr(entry_points, 'select'):
|
|
538
|
+
module_entries = entry_points.select(group='erispulse.module')
|
|
539
|
+
module_entry_map = {entry.name: entry for entry in module_entries}
|
|
540
|
+
else:
|
|
541
|
+
module_entries = entry_points.get('erispulse.module', [])
|
|
542
|
+
module_entry_map = {entry.name: entry for entry in module_entries}
|
|
543
|
+
except Exception as e:
|
|
544
|
+
logger.error(f"获取 entry_points 失败: {e}")
|
|
545
|
+
return False
|
|
546
|
+
|
|
547
|
+
# 第一次遍历:创建所有模块的占位符
|
|
548
|
+
for module_name in modules:
|
|
549
|
+
module_obj = module_objs[module_name]
|
|
550
|
+
meta_name = module_obj.moduleInfo["meta"]["name"]
|
|
551
|
+
|
|
552
|
+
if not mods.get_module_status(meta_name):
|
|
553
|
+
continue
|
|
554
|
+
|
|
555
|
+
entry_point = module_entry_map.get(meta_name)
|
|
556
|
+
if not entry_point:
|
|
557
|
+
logger.error(f"找不到模块 {meta_name} 的 entry-point")
|
|
558
|
+
success = False
|
|
559
|
+
continue
|
|
560
|
+
|
|
561
|
+
# 创建模块占位符
|
|
562
|
+
if not hasattr(sdk, meta_name):
|
|
563
|
+
setattr(sdk, meta_name, None)
|
|
564
|
+
|
|
565
|
+
# 第二次遍历:实际初始化模块
|
|
566
|
+
for module_name in modules:
|
|
567
|
+
module_obj = module_objs[module_name]
|
|
568
|
+
meta_name = module_obj.moduleInfo["meta"]["name"]
|
|
569
|
+
|
|
570
|
+
try:
|
|
571
|
+
if not mods.get_module_status(meta_name):
|
|
572
|
+
continue
|
|
573
|
+
|
|
574
|
+
entry_point = module_entry_map.get(meta_name)
|
|
575
|
+
if not entry_point:
|
|
576
|
+
continue
|
|
577
|
+
|
|
578
|
+
module_class = entry_point.load()
|
|
579
|
+
lazy_load = ModuleLoader._should_lazy_load(module_class)
|
|
580
|
+
|
|
581
|
+
if lazy_load:
|
|
582
|
+
lazy_module = LazyModule(meta_name, module_class, sdk, module_obj.moduleInfo)
|
|
583
|
+
setattr(sdk, meta_name, lazy_module)
|
|
584
|
+
else:
|
|
585
|
+
init_signature = inspect.signature(module_class.__init__)
|
|
586
|
+
if 'sdk' in init_signature.parameters:
|
|
587
|
+
instance = module_class(sdk)
|
|
588
|
+
else:
|
|
589
|
+
instance = module_class()
|
|
590
|
+
|
|
591
|
+
setattr(instance, "moduleInfo", module_obj.moduleInfo)
|
|
592
|
+
setattr(sdk, meta_name, instance)
|
|
593
|
+
logger.debug(f"模块 {meta_name} 已初始化")
|
|
594
|
+
|
|
595
|
+
except Exception as e:
|
|
596
|
+
logger.error(f"初始化模块 {meta_name} 失败: {e}")
|
|
597
|
+
success = False
|
|
598
|
+
|
|
599
|
+
return success
|
|
600
|
+
|
|
601
|
+
def init_progress() -> bool:
|
|
602
|
+
"""
|
|
603
|
+
初始化项目环境文件
|
|
604
|
+
|
|
605
|
+
1. 检查并创建main.py入口文件
|
|
606
|
+
2. 确保基础目录结构存在
|
|
607
|
+
|
|
608
|
+
:return: bool: 是否创建了新的main.py文件
|
|
609
|
+
|
|
610
|
+
{!--< tips >!--}
|
|
611
|
+
1. 如果main.py已存在则不会覆盖
|
|
612
|
+
2. 此方法通常由SDK内部调用
|
|
613
|
+
{!--< /tips >!--}
|
|
614
|
+
"""
|
|
95
615
|
main_file = Path("main.py")
|
|
96
|
-
env_init = False
|
|
97
616
|
main_init = False
|
|
617
|
+
|
|
98
618
|
try:
|
|
99
|
-
if not env_file.exists():
|
|
100
|
-
env_content = '''# env.py
|
|
101
|
-
# ErisPulse 环境配置文件
|
|
102
|
-
# 本文件由 SDK 自动创建,请勿随意删除
|
|
103
|
-
# 配置项可通过 sdk.env.get(key, default) 获取,或使用 sdk.env.set(key, value) 设置
|
|
104
|
-
# 你也可以像写普通变量一样直接定义配置项,例如:
|
|
105
|
-
#
|
|
106
|
-
# MY_CONFIG = "value"
|
|
107
|
-
# MY_CONFIG_2 = {"key": "value"}
|
|
108
|
-
# MY_CONFIG_3 = [1, 2, 3]
|
|
109
|
-
#
|
|
110
|
-
# sdk.env.set("MY_CONFIG", "value")
|
|
111
|
-
# sdk.env.set("MY_CONFIG_2", {"key": "value"})
|
|
112
|
-
# sdk.env.set("MY_CONFIG_3", [1, 2, 3])
|
|
113
|
-
#
|
|
114
|
-
# 这些变量会自动被加载到 SDK 的配置系统中,可通过 sdk.env.MY_CONFIG 或 sdk.env.get("MY_CONFIG") 访问。
|
|
115
|
-
|
|
116
|
-
from ErisPulse import sdk
|
|
117
|
-
'''
|
|
118
|
-
with open(env_file, "w", encoding="utf-8") as f:
|
|
119
|
-
f.write(env_content)
|
|
120
|
-
env_init = True
|
|
121
619
|
if not main_file.exists():
|
|
122
620
|
main_content = '''# main.py
|
|
123
621
|
# ErisPulse 主程序文件
|
|
@@ -145,174 +643,87 @@ if __name__ == "__main__":
|
|
|
145
643
|
with open(main_file, "w", encoding="utf-8") as f:
|
|
146
644
|
f.write(main_content)
|
|
147
645
|
main_init = True
|
|
148
|
-
|
|
646
|
+
|
|
647
|
+
return main_init
|
|
149
648
|
except Exception as e:
|
|
150
649
|
sdk.logger.error(f"无法初始化项目环境: {e}")
|
|
151
650
|
return False
|
|
152
651
|
|
|
652
|
+
|
|
153
653
|
def _prepare_environment() -> bool:
|
|
654
|
+
"""
|
|
655
|
+
{!--< internal-use >!--}
|
|
656
|
+
准备运行环境
|
|
657
|
+
|
|
658
|
+
1. 初始化项目环境文件
|
|
659
|
+
2. 加载环境变量配置
|
|
660
|
+
|
|
661
|
+
:return: bool: 环境准备是否成功
|
|
662
|
+
"""
|
|
154
663
|
logger.info("[Init] 准备初始化环境...")
|
|
155
664
|
try:
|
|
156
|
-
|
|
157
|
-
if env_init:
|
|
158
|
-
logger.info("[Init] 项目首次初始化,建议先配置环境变量")
|
|
159
|
-
if input("是否立即退出?(y/n): ").strip().lower() == "y":
|
|
160
|
-
return False
|
|
665
|
+
main_init = init_progress()
|
|
161
666
|
if main_init:
|
|
162
|
-
logger.info("[Init] 项目入口已生成,
|
|
163
|
-
if input("是否立即退出?(y/n): ").strip().lower() == "y":
|
|
164
|
-
return False
|
|
667
|
+
logger.info("[Init] 项目入口已生成, 你可以在 main.py 中编写一些代码")
|
|
165
668
|
env.load_env_file()
|
|
166
669
|
return True
|
|
167
670
|
except Exception as e:
|
|
168
671
|
logger.error(f"环境准备失败: {e}")
|
|
169
672
|
return False
|
|
170
|
-
def _scan_modules(module_path: str) -> Tuple[Dict, List, List]:
|
|
171
673
|
|
|
172
|
-
# 扫描并验证模块
|
|
173
|
-
module_objs = {}
|
|
174
|
-
enabled_modules = []
|
|
175
|
-
disabled_modules = []
|
|
176
|
-
|
|
177
|
-
if not os.path.exists(module_path):
|
|
178
|
-
os.makedirs(module_path)
|
|
179
|
-
sys.path.append(module_path)
|
|
180
674
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
continue
|
|
189
|
-
|
|
190
|
-
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
191
|
-
module_info = mods.get_module(meta_name) or {
|
|
192
|
-
"status": True,
|
|
193
|
-
"info": moduleObj.moduleInfo
|
|
194
|
-
}
|
|
195
|
-
mods.set_module(meta_name, module_info)
|
|
196
|
-
|
|
197
|
-
if not module_info.get('status', True):
|
|
198
|
-
disabled_modules.append(module_name)
|
|
199
|
-
logger.warning(f"模块 {meta_name} 已禁用,跳过加载")
|
|
200
|
-
continue
|
|
201
|
-
|
|
202
|
-
_check_dependencies(moduleObj, module_name, os.listdir(module_path))
|
|
203
|
-
module_objs[module_name] = moduleObj
|
|
204
|
-
enabled_modules.append(module_name)
|
|
205
|
-
|
|
206
|
-
except Exception as e:
|
|
207
|
-
logger.warning(f"模块 {module_name} 加载失败: {e}")
|
|
208
|
-
|
|
209
|
-
return module_objs, enabled_modules, disabled_modules
|
|
675
|
+
def init() -> bool:
|
|
676
|
+
"""
|
|
677
|
+
SDK初始化入口
|
|
678
|
+
|
|
679
|
+
执行步骤:
|
|
680
|
+
1. 准备运行环境
|
|
681
|
+
2. 初始化所有模块和适配器
|
|
210
682
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
683
|
+
:return: bool: SDK初始化是否成功
|
|
684
|
+
|
|
685
|
+
{!--< tips >!--}
|
|
686
|
+
1. 这是SDK的主要入口函数
|
|
687
|
+
2. 如果初始化失败会抛出InitError异常
|
|
688
|
+
3. 建议在main.py中调用此函数
|
|
689
|
+
{!--< /tips >!--}
|
|
690
|
+
|
|
691
|
+
:raises InitError: 当初始化失败时抛出
|
|
692
|
+
"""
|
|
693
|
+
if not _prepare_environment():
|
|
221
694
|
return False
|
|
222
|
-
return True
|
|
223
|
-
|
|
224
|
-
def _check_dependencies(moduleObj, module_name: str, available_modules: list) -> None:
|
|
225
|
-
# 检查模块依赖关系
|
|
226
|
-
required_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
|
|
227
|
-
if missing := [dep for dep in required_deps if dep not in available_modules]:
|
|
228
|
-
logger.error(f"模块 {module_name} 缺少必需依赖: {missing}")
|
|
229
|
-
raiserr.MissingDependencyError(f"模块 {module_name} 缺少必需依赖: {missing}")
|
|
230
|
-
|
|
231
|
-
optional_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
|
|
232
|
-
available_optional = [
|
|
233
|
-
dep for dep in optional_deps
|
|
234
|
-
if (isinstance(dep, list) and any(d in available_modules for d in dep))
|
|
235
|
-
or (not isinstance(dep, list) and dep in available_modules)
|
|
236
|
-
]
|
|
237
|
-
if optional_deps and not available_optional:
|
|
238
|
-
logger.warning(f"模块 {module_name} 缺少所有可选依赖: {optional_deps}")
|
|
239
|
-
|
|
240
|
-
def _resolve_dependencies(modules: list, module_objs: dict) -> list:
|
|
241
|
-
# 解析模块依赖关系并进行拓扑排序
|
|
242
|
-
dependencies = {}
|
|
243
|
-
for module_name in modules:
|
|
244
|
-
moduleObj = module_objs[module_name]
|
|
245
|
-
req_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
|
|
246
|
-
opt_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
|
|
247
|
-
available_opt = [dep for dep in opt_deps if dep in modules]
|
|
248
|
-
dependencies[module_name] = req_deps + available_opt
|
|
249
|
-
|
|
250
|
-
sorted_modules = sdk.util.topological_sort(modules, dependencies, raiserr.CycleDependencyError)
|
|
251
|
-
env.set('module_dependencies', {
|
|
252
|
-
'modules': sorted_modules,
|
|
253
|
-
'dependencies': dependencies
|
|
254
|
-
})
|
|
255
|
-
return sorted_modules
|
|
256
|
-
|
|
257
|
-
def _register_adapters(modules: list, module_objs: dict) -> bool:
|
|
258
|
-
# 注册适配器
|
|
259
|
-
success = True
|
|
260
|
-
logger.debug("[Init] 开始注册适配器...")
|
|
261
|
-
for module_name in modules:
|
|
262
|
-
moduleObj = module_objs[module_name]
|
|
263
|
-
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
264
|
-
|
|
265
|
-
try:
|
|
266
|
-
if hasattr(moduleObj, "adapterInfo") and isinstance(moduleObj.adapterInfo, dict):
|
|
267
|
-
for platform, adapter_class in moduleObj.adapterInfo.items():
|
|
268
|
-
sdk.adapter.register(platform, adapter_class)
|
|
269
|
-
logger.info(f"模块 {meta_name} 注册适配器: {platform}")
|
|
270
|
-
except Exception as e:
|
|
271
|
-
logger.error(f"模块 {meta_name} 适配器注册失败: {e}")
|
|
272
|
-
success = False
|
|
273
|
-
return success
|
|
274
|
-
|
|
275
|
-
def _initialize_modules(modules: list, module_objs: dict) -> bool:
|
|
276
|
-
# 初始化模块
|
|
277
|
-
success = True
|
|
278
|
-
logger.debug("[Init] 开始实例化模块...")
|
|
279
|
-
for module_name in modules:
|
|
280
|
-
moduleObj = module_objs[module_name]
|
|
281
|
-
meta_name = moduleObj.moduleInfo["meta"]["name"]
|
|
282
|
-
|
|
283
|
-
try:
|
|
284
|
-
if mods.get_module_status(meta_name):
|
|
285
|
-
moduleMain = moduleObj.Main(sdk)
|
|
286
|
-
setattr(moduleMain, "moduleInfo", moduleObj.moduleInfo)
|
|
287
|
-
setattr(sdk, meta_name, moduleMain)
|
|
288
|
-
logger.debug(f"模块 {meta_name} 初始化完成")
|
|
289
|
-
except Exception as e:
|
|
290
|
-
logger.error(f"模块 {meta_name} 初始化失败: {e}")
|
|
291
|
-
success = False
|
|
292
|
-
return success
|
|
293
695
|
|
|
294
|
-
|
|
295
|
-
|
|
696
|
+
return ModuleInitializer.init()
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
def load_module(module_name: str) -> bool:
|
|
700
|
+
"""
|
|
701
|
+
手动加载指定模块
|
|
702
|
+
|
|
703
|
+
:param module_name: 要加载的模块名称
|
|
704
|
+
:return: bool: 加载是否成功
|
|
705
|
+
|
|
706
|
+
{!--< tips >!--}
|
|
707
|
+
1. 可用于手动触发懒加载模块的初始化
|
|
708
|
+
2. 如果模块不存在或已加载会返回False
|
|
709
|
+
{!--< /tips >!--}
|
|
710
|
+
"""
|
|
296
711
|
try:
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
module_objs, enabled_modules, _ = _scan_modules(module_path)
|
|
302
|
-
|
|
303
|
-
if not enabled_modules:
|
|
304
|
-
logger.warning("没有找到可用的模块")
|
|
712
|
+
module = getattr(sdk, module_name, None)
|
|
713
|
+
if isinstance(module, LazyModule):
|
|
714
|
+
# 触发懒加载模块的初始化
|
|
715
|
+
module._initialize()
|
|
305
716
|
return True
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
717
|
+
elif module is not None:
|
|
718
|
+
logger.warning(f"模块 {module_name} 已经加载")
|
|
719
|
+
return False
|
|
720
|
+
else:
|
|
721
|
+
logger.error(f"模块 {module_name} 不存在")
|
|
309
722
|
return False
|
|
310
|
-
|
|
311
|
-
return _initialize_modules(sorted_modules, module_objs)
|
|
312
|
-
|
|
313
723
|
except Exception as e:
|
|
314
|
-
logger.
|
|
315
|
-
raiserr.InitError(f"sdk初始化失败: {e}", exit=True)
|
|
724
|
+
logger.error(f"加载模块 {module_name} 失败: {e}")
|
|
316
725
|
return False
|
|
317
726
|
|
|
318
|
-
|
|
727
|
+
|
|
728
|
+
sdk.init = init
|
|
729
|
+
sdk.load_module = load_module
|