ErisPulse 1.2.9__py3-none-any.whl → 2.1.1__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 +548 -0
- ErisPulse/Core/env.py +614 -0
- ErisPulse/{logger.py → Core/logger.py} +51 -113
- 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 +673 -243
- ErisPulse/__main__.py +391 -1184
- {erispulse-1.2.9.dist-info → erispulse-2.1.1.dist-info}/METADATA +16 -41
- erispulse-2.1.1.dist-info/RECORD +16 -0
- {erispulse-1.2.9.dist-info → erispulse-2.1.1.dist-info}/entry_points.txt +1 -0
- {erispulse-1.2.9.dist-info → erispulse-2.1.1.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.1.dist-info}/WHEEL +0 -0
ErisPulse/mods.py
DELETED
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
# 模块管理系统
|
|
3
|
-
|
|
4
|
-
提供模块的注册、状态管理和依赖解析功能。支持模块信息存储、状态切换和批量操作。
|
|
5
|
-
|
|
6
|
-
## API 文档
|
|
7
|
-
|
|
8
|
-
### 模块状态管理
|
|
9
|
-
#### set_module_status(module_name: str, status: bool) -> None
|
|
10
|
-
设置模块的启用状态。
|
|
11
|
-
- 参数:
|
|
12
|
-
- module_name: 模块名称
|
|
13
|
-
- status: 模块状态,True为启用,False为禁用
|
|
14
|
-
- 返回:
|
|
15
|
-
- None
|
|
16
|
-
- 示例:
|
|
17
|
-
```python
|
|
18
|
-
# 启用模块
|
|
19
|
-
sdk.mods.set_module_status("MyModule", True)
|
|
20
|
-
|
|
21
|
-
# 禁用模块
|
|
22
|
-
sdk.mods.set_module_status("MyModule", False)
|
|
23
|
-
|
|
24
|
-
# 条件性启用模块
|
|
25
|
-
if check_dependencies():
|
|
26
|
-
sdk.mods.set_module_status("MyModule", True)
|
|
27
|
-
else:
|
|
28
|
-
sdk.logger.warning("依赖检查失败,模块未启用")
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
#### get_module_status(module_name: str) -> bool
|
|
32
|
-
获取模块的启用状态。
|
|
33
|
-
- 参数:
|
|
34
|
-
- module_name: 模块名称
|
|
35
|
-
- 返回:
|
|
36
|
-
- bool: 模块状态,True为启用,False为禁用
|
|
37
|
-
- 示例:
|
|
38
|
-
```python
|
|
39
|
-
# 检查模块是否启用
|
|
40
|
-
if sdk.mods.get_module_status("MyModule"):
|
|
41
|
-
print("模块已启用")
|
|
42
|
-
else:
|
|
43
|
-
print("模块已禁用")
|
|
44
|
-
|
|
45
|
-
# 在条件中使用
|
|
46
|
-
if sdk.mods.get_module_status("DatabaseModule") and sdk.mods.get_module_status("NetworkModule"):
|
|
47
|
-
start_application()
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### 模块信息管理
|
|
51
|
-
#### set_module(module_name: str, module_info: dict) -> None
|
|
52
|
-
设置模块信息。
|
|
53
|
-
- 参数:
|
|
54
|
-
- module_name: 模块名称
|
|
55
|
-
- module_info: 模块信息字典,包含模块的元数据和配置
|
|
56
|
-
- 返回:
|
|
57
|
-
- None
|
|
58
|
-
- 示例:
|
|
59
|
-
```python
|
|
60
|
-
# 设置基本模块信息
|
|
61
|
-
sdk.mods.set_module("MyModule", {
|
|
62
|
-
"status": True,
|
|
63
|
-
"info": {
|
|
64
|
-
"meta": {
|
|
65
|
-
"name": "MyModule",
|
|
66
|
-
"version": "1.0.0",
|
|
67
|
-
"description": "示例模块",
|
|
68
|
-
"author": "开发者"
|
|
69
|
-
},
|
|
70
|
-
"dependencies": {
|
|
71
|
-
"requires": ["CoreModule"],
|
|
72
|
-
"optional": ["OptionalModule"],
|
|
73
|
-
"pip": ["requests", "numpy"]
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
# 更新现有模块信息
|
|
79
|
-
module_info = sdk.mods.get_module("MyModule")
|
|
80
|
-
module_info["info"]["meta"]["version"] = "1.1.0"
|
|
81
|
-
sdk.mods.set_module("MyModule", module_info)
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
#### get_module(module_name: str) -> dict
|
|
85
|
-
获取模块信息。
|
|
86
|
-
- 参数:
|
|
87
|
-
- module_name: 模块名称
|
|
88
|
-
- 返回:
|
|
89
|
-
- dict: 模块信息字典
|
|
90
|
-
- None: 如果模块不存在
|
|
91
|
-
- 示例:
|
|
92
|
-
```python
|
|
93
|
-
# 获取模块信息
|
|
94
|
-
module_info = sdk.mods.get_module("MyModule")
|
|
95
|
-
if module_info:
|
|
96
|
-
print(f"模块版本: {module_info['info']['meta']['version']}")
|
|
97
|
-
print(f"模块描述: {module_info['info']['meta']['description']}")
|
|
98
|
-
print(f"模块状态: {'启用' if module_info['status'] else '禁用'}")
|
|
99
|
-
else:
|
|
100
|
-
print("模块不存在")
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
#### get_all_modules() -> dict
|
|
104
|
-
获取所有模块信息。
|
|
105
|
-
- 参数: 无
|
|
106
|
-
- 返回:
|
|
107
|
-
- dict: 包含所有模块信息的字典,键为模块名,值为模块信息
|
|
108
|
-
- 示例:
|
|
109
|
-
```python
|
|
110
|
-
# 获取所有模块
|
|
111
|
-
all_modules = sdk.mods.get_all_modules()
|
|
112
|
-
|
|
113
|
-
# 统计启用和禁用的模块
|
|
114
|
-
enabled_count = 0
|
|
115
|
-
disabled_count = 0
|
|
116
|
-
for name, info in all_modules.items():
|
|
117
|
-
if info.get("status", False):
|
|
118
|
-
enabled_count += 1
|
|
119
|
-
else:
|
|
120
|
-
disabled_count += 1
|
|
121
|
-
|
|
122
|
-
print(f"已启用模块: {enabled_count}")
|
|
123
|
-
print(f"已禁用模块: {disabled_count}")
|
|
124
|
-
|
|
125
|
-
# 查找特定类型的模块
|
|
126
|
-
adapters = [name for name, info in all_modules.items()
|
|
127
|
-
if "adapter" in info.get("info", {}).get("meta", {}).get("tags", [])]
|
|
128
|
-
print(f"适配器模块: {adapters}")
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
#### update_module(module_name: str, module_info: dict) -> None
|
|
132
|
-
更新模块信息。
|
|
133
|
-
- 参数:
|
|
134
|
-
- module_name: 模块名称
|
|
135
|
-
- module_info: 更新后的模块信息字典
|
|
136
|
-
- 返回:
|
|
137
|
-
- None
|
|
138
|
-
- 示例:
|
|
139
|
-
```python
|
|
140
|
-
# 更新模块版本
|
|
141
|
-
module_info = sdk.mods.get_module("MyModule")
|
|
142
|
-
module_info["info"]["meta"]["version"] = "1.2.0"
|
|
143
|
-
sdk.mods.update_module("MyModule", module_info)
|
|
144
|
-
|
|
145
|
-
# 添加新的配置项
|
|
146
|
-
module_info = sdk.mods.get_module("MyModule")
|
|
147
|
-
if "config" not in module_info:
|
|
148
|
-
module_info["config"] = {}
|
|
149
|
-
module_info["config"]["debug_mode"] = True
|
|
150
|
-
sdk.mods.update_module("MyModule", module_info)
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
#### remove_module(module_name: str) -> bool
|
|
154
|
-
删除模块。
|
|
155
|
-
- 参数:
|
|
156
|
-
- module_name: 模块名称
|
|
157
|
-
- 返回:
|
|
158
|
-
- bool: 是否成功删除
|
|
159
|
-
- 示例:
|
|
160
|
-
```python
|
|
161
|
-
# 删除模块
|
|
162
|
-
if sdk.mods.remove_module("OldModule"):
|
|
163
|
-
print("模块已成功删除")
|
|
164
|
-
else:
|
|
165
|
-
print("模块不存在或删除失败")
|
|
166
|
-
|
|
167
|
-
# 条件删除
|
|
168
|
-
if sdk.mods.get_module_status("TestModule") and is_test_environment():
|
|
169
|
-
sdk.mods.remove_module("TestModule")
|
|
170
|
-
print("测试模块已在生产环境中移除")
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
#### set_all_modules(modules_info: Dict[str, dict]) -> None
|
|
174
|
-
批量设置多个模块信息。
|
|
175
|
-
- 参数:
|
|
176
|
-
- modules_info: 模块信息字典的字典,键为模块名,值为模块信息
|
|
177
|
-
- 返回:
|
|
178
|
-
- None
|
|
179
|
-
- 示例:
|
|
180
|
-
```python
|
|
181
|
-
# 批量设置模块
|
|
182
|
-
sdk.mods.set_all_modules({
|
|
183
|
-
"Module1": {
|
|
184
|
-
"status": True,
|
|
185
|
-
"info": {"meta": {"name": "Module1", "version": "1.0.0"}}
|
|
186
|
-
},
|
|
187
|
-
"Module2": {
|
|
188
|
-
"status": True,
|
|
189
|
-
"info": {"meta": {"name": "Module2", "version": "1.0.0"}}
|
|
190
|
-
}
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
# 从配置文件加载模块信息
|
|
194
|
-
import json
|
|
195
|
-
with open("modules_config.json", "r") as f:
|
|
196
|
-
modules_config = json.load(f)
|
|
197
|
-
sdk.mods.set_all_modules(modules_config)
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### 前缀管理
|
|
201
|
-
#### update_prefixes(module_prefix: str = None, status_prefix: str = None) -> None
|
|
202
|
-
更新存储前缀。
|
|
203
|
-
- 参数:
|
|
204
|
-
- module_prefix: 模块存储前缀
|
|
205
|
-
- status_prefix: 状态存储前缀
|
|
206
|
-
- 返回:
|
|
207
|
-
- None
|
|
208
|
-
- 示例:
|
|
209
|
-
```python
|
|
210
|
-
# 更新模块前缀
|
|
211
|
-
sdk.mods.update_prefixes(module_prefix="custom.module.")
|
|
212
|
-
|
|
213
|
-
# 更新状态前缀
|
|
214
|
-
sdk.mods.update_prefixes(status_prefix="custom.status.")
|
|
215
|
-
|
|
216
|
-
# 同时更新两个前缀
|
|
217
|
-
sdk.mods.update_prefixes(
|
|
218
|
-
module_prefix="app.modules.",
|
|
219
|
-
status_prefix="app.status."
|
|
220
|
-
)
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
#### module_prefix 属性
|
|
224
|
-
获取当前模块存储前缀。
|
|
225
|
-
- 返回:
|
|
226
|
-
- str: 当前模块存储前缀
|
|
227
|
-
- 示例:
|
|
228
|
-
```python
|
|
229
|
-
# 获取当前模块前缀
|
|
230
|
-
prefix = sdk.mods.module_prefix
|
|
231
|
-
print(f"当前模块前缀: {prefix}")
|
|
232
|
-
|
|
233
|
-
# 在自定义存储操作中使用
|
|
234
|
-
custom_key = f"{sdk.mods.module_prefix}custom.{module_name}"
|
|
235
|
-
sdk.env.set(custom_key, custom_data)
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
#### status_prefix 属性
|
|
239
|
-
获取当前状态存储前缀。
|
|
240
|
-
- 返回:
|
|
241
|
-
- str: 当前状态存储前缀
|
|
242
|
-
- 示例:
|
|
243
|
-
```python
|
|
244
|
-
# 获取当前状态前缀
|
|
245
|
-
prefix = sdk.mods.status_prefix
|
|
246
|
-
print(f"当前状态前缀: {prefix}")
|
|
247
|
-
|
|
248
|
-
# 在自定义状态操作中使用
|
|
249
|
-
custom_status_key = f"{sdk.mods.status_prefix}custom.{module_name}"
|
|
250
|
-
sdk.env.set(custom_status_key, is_active)
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
"""
|
|
254
|
-
|
|
255
|
-
import json
|
|
256
|
-
from typing import Dict, Optional, Any, List, Set, Tuple, Union, Type, FrozenSet
|
|
257
|
-
|
|
258
|
-
class ModuleManager:
|
|
259
|
-
DEFAULT_MODULE_PREFIX = "erispulse.module.data:"
|
|
260
|
-
DEFAULT_STATUS_PREFIX = "erispulse.module.status:"
|
|
261
|
-
|
|
262
|
-
def __init__(self):
|
|
263
|
-
from .db import env
|
|
264
|
-
self.env = env
|
|
265
|
-
self._ensure_prefixes()
|
|
266
|
-
|
|
267
|
-
def _ensure_prefixes(self):
|
|
268
|
-
if not self.env.get("erispulse.system.module_prefix"):
|
|
269
|
-
self.env.set("erispulse.system.module_prefix", self.DEFAULT_MODULE_PREFIX)
|
|
270
|
-
if not self.env.get("erispulse.system.status_prefix"):
|
|
271
|
-
self.env.set("erispulse.system.status_prefix", self.DEFAULT_STATUS_PREFIX)
|
|
272
|
-
|
|
273
|
-
@property
|
|
274
|
-
def module_prefix(self) -> str:
|
|
275
|
-
return self.env.get("erispulse.system.module_prefix")
|
|
276
|
-
|
|
277
|
-
@property
|
|
278
|
-
def status_prefix(self) -> str:
|
|
279
|
-
return self.env.get("erispulse.system.status_prefix")
|
|
280
|
-
|
|
281
|
-
def set_module_status(self, module_name: str, status: bool) -> None:
|
|
282
|
-
self.env.set(f"{self.status_prefix}{module_name}", bool(status))
|
|
283
|
-
|
|
284
|
-
module_info = self.get_module(module_name)
|
|
285
|
-
if module_info:
|
|
286
|
-
module_info["status"] = bool(status)
|
|
287
|
-
self.env.set(f"{self.module_prefix}{module_name}", module_info)
|
|
288
|
-
|
|
289
|
-
def get_module_status(self, module_name: str) -> bool:
|
|
290
|
-
status = self.env.get(f"{self.status_prefix}{module_name}", True)
|
|
291
|
-
if isinstance(status, str):
|
|
292
|
-
return status.lower() == 'true'
|
|
293
|
-
return bool(status)
|
|
294
|
-
|
|
295
|
-
def set_module(self, module_name: str, module_info: dict) -> None:
|
|
296
|
-
self.env.set(f"{self.module_prefix}{module_name}", module_info)
|
|
297
|
-
self.set_module_status(module_name, module_info.get('status', True))
|
|
298
|
-
|
|
299
|
-
def get_module(self, module_name: str) -> Optional[dict]:
|
|
300
|
-
return self.env.get(f"{self.module_prefix}{module_name}")
|
|
301
|
-
|
|
302
|
-
def set_all_modules(self, modules_info: Dict[str, dict]) -> None:
|
|
303
|
-
for module_name, module_info in modules_info.items():
|
|
304
|
-
self.set_module(module_name, module_info)
|
|
305
|
-
|
|
306
|
-
def get_all_modules(self) -> dict:
|
|
307
|
-
modules_info = {}
|
|
308
|
-
all_keys = self.env.get_all_keys()
|
|
309
|
-
prefix_len = len(self.module_prefix)
|
|
310
|
-
|
|
311
|
-
for key in all_keys:
|
|
312
|
-
if key.startswith(self.module_prefix):
|
|
313
|
-
module_name = key[prefix_len:]
|
|
314
|
-
module_info = self.get_module(module_name)
|
|
315
|
-
if module_info:
|
|
316
|
-
status = self.get_module_status(module_name)
|
|
317
|
-
module_info['status'] = bool(status)
|
|
318
|
-
modules_info[module_name] = module_info
|
|
319
|
-
return modules_info
|
|
320
|
-
|
|
321
|
-
def update_module(self, module_name: str, module_info: dict) -> None:
|
|
322
|
-
self.set_module(module_name, module_info)
|
|
323
|
-
|
|
324
|
-
def remove_module(self, module_name: str) -> bool:
|
|
325
|
-
module_key = f"{self.module_prefix}{module_name}"
|
|
326
|
-
status_key = f"{self.status_prefix}{module_name}"
|
|
327
|
-
|
|
328
|
-
if self.env.get(module_key) is not None:
|
|
329
|
-
self.env.delete(module_key)
|
|
330
|
-
self.env.delete(status_key)
|
|
331
|
-
return True
|
|
332
|
-
return False
|
|
333
|
-
|
|
334
|
-
def update_prefixes(self, module_prefix: str = None, status_prefix: str = None) -> None:
|
|
335
|
-
if module_prefix:
|
|
336
|
-
if not module_prefix.endswith(':'):
|
|
337
|
-
module_prefix += ':'
|
|
338
|
-
self.env.set("erispulse.system.module_prefix", module_prefix)
|
|
339
|
-
|
|
340
|
-
if status_prefix:
|
|
341
|
-
if not status_prefix.endswith(':'):
|
|
342
|
-
status_prefix += ':'
|
|
343
|
-
self.env.set("erispulse.system.status_prefix", status_prefix)
|
|
344
|
-
|
|
345
|
-
mods = ModuleManager()
|
ErisPulse/raiserr.py
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
# 错误管理系统
|
|
3
|
-
|
|
4
|
-
提供错误类型注册、抛出和管理功能,集成全局异常处理。支持自定义错误类型、错误链追踪和全局异常捕获。
|
|
5
|
-
|
|
6
|
-
## API 文档
|
|
7
|
-
|
|
8
|
-
### 错误注册
|
|
9
|
-
#### register(name: str, doc: str = "", base: type = Exception) -> type
|
|
10
|
-
注册新的错误类型。
|
|
11
|
-
- 参数:
|
|
12
|
-
- name: 错误类型名称
|
|
13
|
-
- doc: 错误描述文档
|
|
14
|
-
- base: 基础异常类,默认为Exception
|
|
15
|
-
- 返回:
|
|
16
|
-
- type: 注册的错误类型类
|
|
17
|
-
- 示例:
|
|
18
|
-
```python
|
|
19
|
-
# 注册一个简单错误
|
|
20
|
-
sdk.raiserr.register("SimpleError", "简单的错误类型")
|
|
21
|
-
|
|
22
|
-
# 注册带有自定义基类的错误
|
|
23
|
-
class CustomBase(Exception):
|
|
24
|
-
pass
|
|
25
|
-
sdk.raiserr.register("AdvancedError", "高级错误", CustomBase)
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
#### info(name: str = None) -> Dict[str, Any] or None
|
|
29
|
-
获取错误类型信息。
|
|
30
|
-
- 参数:
|
|
31
|
-
- name: 错误类型名称,如果为None则返回所有错误类型信息
|
|
32
|
-
- 返回:
|
|
33
|
-
- Dict[str, Any]: 包含错误类型信息的字典,包括类型名、文档和类引用
|
|
34
|
-
- None: 如果指定的错误类型不存在
|
|
35
|
-
- 示例:
|
|
36
|
-
```python
|
|
37
|
-
# 获取特定错误信息
|
|
38
|
-
error_info = sdk.raiserr.info("SimpleError")
|
|
39
|
-
print(f"错误类型: {error_info['type']}")
|
|
40
|
-
print(f"错误描述: {error_info['doc']}")
|
|
41
|
-
|
|
42
|
-
# 获取所有注册的错误信息
|
|
43
|
-
all_errors = sdk.raiserr.info()
|
|
44
|
-
for name, info in all_errors.items():
|
|
45
|
-
print(f"{name}: {info['doc']}")
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### 错误抛出
|
|
49
|
-
#### ErrorType(msg: str, exit: bool = False)
|
|
50
|
-
动态生成的错误抛出函数。
|
|
51
|
-
- 参数:
|
|
52
|
-
- msg: 错误消息
|
|
53
|
-
- exit: 是否在抛出错误后退出程序
|
|
54
|
-
- 示例:
|
|
55
|
-
```python
|
|
56
|
-
# 抛出不退出的错误
|
|
57
|
-
sdk.raiserr.SimpleError("操作失败")
|
|
58
|
-
|
|
59
|
-
# 抛出导致程序退出的错误
|
|
60
|
-
sdk.raiserr.CriticalError("致命错误", exit=True)
|
|
61
|
-
|
|
62
|
-
# 带有异常捕获的使用方式
|
|
63
|
-
try:
|
|
64
|
-
sdk.raiserr.ValidationError("数据验证失败")
|
|
65
|
-
except Exception as e:
|
|
66
|
-
print(f"捕获到错误: {e}")
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
"""
|
|
70
|
-
|
|
71
|
-
import sys
|
|
72
|
-
import traceback
|
|
73
|
-
import asyncio
|
|
74
|
-
from typing import Dict, Any, Optional, Type, List, Set, Tuple, Union
|
|
75
|
-
|
|
76
|
-
class Error:
|
|
77
|
-
def __init__(self):
|
|
78
|
-
self._types = {}
|
|
79
|
-
|
|
80
|
-
def register(self, name, doc="", base=Exception) -> Type:
|
|
81
|
-
if name not in self._types:
|
|
82
|
-
err_cls = type(name, (base,), {"__doc__": doc})
|
|
83
|
-
self._types[name] = err_cls
|
|
84
|
-
return self._types[name]
|
|
85
|
-
|
|
86
|
-
def __getattr__(self, name):
|
|
87
|
-
def raiser(msg, exit=False):
|
|
88
|
-
from .logger import logger
|
|
89
|
-
err_cls = self._types.get(name) or self.register(name)
|
|
90
|
-
exc = err_cls(msg)
|
|
91
|
-
|
|
92
|
-
red = '\033[91m'
|
|
93
|
-
reset = '\033[0m'
|
|
94
|
-
|
|
95
|
-
logger.error(f"{red}{name}: {msg} | {err_cls.__doc__}{reset}")
|
|
96
|
-
logger.error(f"{red}{ ''.join(traceback.format_stack()) }{reset}")
|
|
97
|
-
|
|
98
|
-
if exit:
|
|
99
|
-
raise exc
|
|
100
|
-
return raiser
|
|
101
|
-
|
|
102
|
-
def info(self, name: str = None) -> Dict[str, Any]:
|
|
103
|
-
result = {}
|
|
104
|
-
for err_name, err_cls in self._types.items():
|
|
105
|
-
result[err_name] = {
|
|
106
|
-
"type": err_name,
|
|
107
|
-
"doc": getattr(err_cls, "__doc__", ""),
|
|
108
|
-
"class": err_cls,
|
|
109
|
-
}
|
|
110
|
-
if name is None:
|
|
111
|
-
return result
|
|
112
|
-
err_cls = self._types.get(name)
|
|
113
|
-
if not err_cls:
|
|
114
|
-
return {
|
|
115
|
-
"type": None,
|
|
116
|
-
"doc": None,
|
|
117
|
-
"class": None,
|
|
118
|
-
}
|
|
119
|
-
return {
|
|
120
|
-
"type": name,
|
|
121
|
-
"doc": getattr(err_cls, "__doc__", ""),
|
|
122
|
-
"class": err_cls,
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
raiserr = Error()
|
|
126
|
-
|
|
127
|
-
# 全局异常处理器
|
|
128
|
-
def global_exception_handler(exc_type, exc_value, exc_traceback):
|
|
129
|
-
error_message = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
|
|
130
|
-
raiserr.ExternalError(
|
|
131
|
-
f"{exc_type.__name__}: {exc_value}\nTraceback:\n{error_message}"
|
|
132
|
-
)
|
|
133
|
-
def async_exception_handler(loop, context):
|
|
134
|
-
exception = context.get('exception')
|
|
135
|
-
tb = ''.join(traceback.format_exception(type(exception), exception, exception.__traceback__))
|
|
136
|
-
raiserr.ExternalError(
|
|
137
|
-
f"{type(exception).__name__}: {exception}\nTraceback:\n{tb}"
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
sys.excepthook = global_exception_handler
|
|
141
|
-
asyncio.get_event_loop().set_exception_handler(async_exception_handler)
|
ErisPulse/util.py
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
# 工具函数集合
|
|
3
|
-
|
|
4
|
-
提供各种实用工具函数和装饰器,简化开发流程。
|
|
5
|
-
|
|
6
|
-
## API 文档
|
|
7
|
-
### 拓扑排序:
|
|
8
|
-
- topological_sort(elements: List[str], dependencies: Dict[str, List[str]], error: Type[Exception]) -> List[str]: 拓扑排序依赖关系
|
|
9
|
-
- show_topology() -> str: 可视化模块依赖关系
|
|
10
|
-
|
|
11
|
-
### 装饰器:
|
|
12
|
-
- @cache: 缓存函数结果
|
|
13
|
-
- @run_in_executor: 将同步函数转为异步
|
|
14
|
-
- @retry(max_attempts=3, delay=1): 失败自动重试
|
|
15
|
-
|
|
16
|
-
### 异步执行:
|
|
17
|
-
- ExecAsync(async_func: Callable, *args: Any, **kwargs: Any) -> Any: 异步执行函数
|
|
18
|
-
|
|
19
|
-
### 示例用法:
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
from ErisPulse import sdk
|
|
23
|
-
|
|
24
|
-
# 拓扑排序
|
|
25
|
-
sorted_modules = sdk.util.topological_sort(modules, dependencies, error)
|
|
26
|
-
|
|
27
|
-
# 缓存装饰器
|
|
28
|
-
@sdk.util.cache
|
|
29
|
-
def expensive_operation(param):
|
|
30
|
-
return heavy_computation(param)
|
|
31
|
-
|
|
32
|
-
# 异步执行
|
|
33
|
-
@sdk.util.run_in_executor
|
|
34
|
-
def sync_task():
|
|
35
|
-
pass
|
|
36
|
-
|
|
37
|
-
# 重试机制
|
|
38
|
-
@sdk.util.retry(max_attempts=3, delay=1)
|
|
39
|
-
def unreliable_operation():
|
|
40
|
-
pass
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
import time
|
|
46
|
-
import asyncio
|
|
47
|
-
import functools
|
|
48
|
-
import traceback
|
|
49
|
-
from concurrent.futures import ThreadPoolExecutor
|
|
50
|
-
from collections import defaultdict, deque
|
|
51
|
-
from typing import List, Dict, Type, Callable, Any, Optional, Set
|
|
52
|
-
|
|
53
|
-
executor = ThreadPoolExecutor()
|
|
54
|
-
|
|
55
|
-
def topological_sort(elements, dependencies, error) -> List[str]:
|
|
56
|
-
graph = defaultdict(list)
|
|
57
|
-
in_degree = {element: 0 for element in elements}
|
|
58
|
-
for element, deps in dependencies.items():
|
|
59
|
-
for dep in deps:
|
|
60
|
-
graph[dep].append(element)
|
|
61
|
-
in_degree[element] += 1
|
|
62
|
-
queue = deque([element for element in elements if in_degree[element] == 0])
|
|
63
|
-
sorted_list = []
|
|
64
|
-
while queue:
|
|
65
|
-
node = queue.popleft()
|
|
66
|
-
sorted_list.append(node)
|
|
67
|
-
for neighbor in graph[node]:
|
|
68
|
-
in_degree[neighbor] -= 1
|
|
69
|
-
if in_degree[neighbor] == 0:
|
|
70
|
-
queue.append(neighbor)
|
|
71
|
-
if len(sorted_list) != len(elements):
|
|
72
|
-
from . import sdk
|
|
73
|
-
sdk.logger.error(f"依赖导入错误: {elements} vs {sorted_list} | 发生了循环依赖")
|
|
74
|
-
return sorted_list
|
|
75
|
-
|
|
76
|
-
def show_topology() -> str:
|
|
77
|
-
from . import sdk
|
|
78
|
-
dep_data = sdk.env.get('module_dependencies')
|
|
79
|
-
if not dep_data:
|
|
80
|
-
return "未找到模块依赖关系数据,请先运行sdk.init()"
|
|
81
|
-
|
|
82
|
-
sorted_modules = topological_sort(
|
|
83
|
-
dep_data['modules'],
|
|
84
|
-
dep_data['dependencies'],
|
|
85
|
-
sdk.raiserr.CycleDependencyError
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
tree = {}
|
|
89
|
-
for module in sorted_modules:
|
|
90
|
-
tree[module] = dep_data['dependencies'].get(module, [])
|
|
91
|
-
|
|
92
|
-
result = ["模块拓扑关系表:"]
|
|
93
|
-
for i, module in enumerate(sorted_modules, 1):
|
|
94
|
-
deps = dep_data['dependencies'].get(module, [])
|
|
95
|
-
indent = " " * (len(deps) if deps else 0)
|
|
96
|
-
result.append(f"{i}. {indent}{module}")
|
|
97
|
-
if deps:
|
|
98
|
-
result.append(f" {indent}└─ 依赖: {', '.join(deps)}")
|
|
99
|
-
|
|
100
|
-
return "\n".join(result)
|
|
101
|
-
|
|
102
|
-
def ExecAsync(async_func, *args, **kwargs) -> Any:
|
|
103
|
-
loop = asyncio.get_event_loop()
|
|
104
|
-
return loop.run_in_executor(executor, lambda: asyncio.run(async_func(*args, **kwargs)))
|
|
105
|
-
|
|
106
|
-
def cache(func):
|
|
107
|
-
cache_dict = {}
|
|
108
|
-
@functools.wraps(func)
|
|
109
|
-
def wrapper(*args, **kwargs):
|
|
110
|
-
key = (args, tuple(sorted(kwargs.items())))
|
|
111
|
-
if key not in cache_dict:
|
|
112
|
-
cache_dict[key] = func(*args, **kwargs)
|
|
113
|
-
return cache_dict[key]
|
|
114
|
-
return wrapper
|
|
115
|
-
|
|
116
|
-
def run_in_executor(func):
|
|
117
|
-
@functools.wraps(func)
|
|
118
|
-
async def wrapper(*args, **kwargs):
|
|
119
|
-
loop = asyncio.get_event_loop()
|
|
120
|
-
try:
|
|
121
|
-
return await loop.run_in_executor(None, lambda: func(*args, **kwargs))
|
|
122
|
-
except Exception as e:
|
|
123
|
-
from . import sdk
|
|
124
|
-
sdk.logger.error(f"线程内发生未处理异常:\n{''.join(traceback.format_exc())}")
|
|
125
|
-
sdk.raiserr.CaughtExternalError(
|
|
126
|
-
f"检测到线程内异常,请优先使用 sdk.raiserr 抛出错误。\n原始异常: {type(e).__name__}: {e}"
|
|
127
|
-
)
|
|
128
|
-
return wrapper
|
|
129
|
-
|
|
130
|
-
def retry(max_attempts=3, delay=1):
|
|
131
|
-
def decorator(func):
|
|
132
|
-
@functools.wraps(func)
|
|
133
|
-
def wrapper(*args, **kwargs):
|
|
134
|
-
attempts = 0
|
|
135
|
-
while attempts < max_attempts:
|
|
136
|
-
try:
|
|
137
|
-
return func(*args, **kwargs)
|
|
138
|
-
except Exception as e:
|
|
139
|
-
attempts += 1
|
|
140
|
-
if attempts == max_attempts:
|
|
141
|
-
raise
|
|
142
|
-
time.sleep(delay)
|
|
143
|
-
return wrapper
|
|
144
|
-
return decorator
|
erispulse-1.2.9.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
ErisPulse/__init__.py,sha256=2hEVWxKaDfFGAe3ekpUFx5tIub2riwDtSscsfpA0T2w,11108
|
|
2
|
-
ErisPulse/__main__.py,sha256=MQ_npNFErw5m8My092apQ4gyZAL-7VPLL9Wc7HTq4f4,56451
|
|
3
|
-
ErisPulse/adapter.py,sha256=sho8HMYVSa3syovU2mDxV2Wsw99yD5_sFz6UER89Tes,14367
|
|
4
|
-
ErisPulse/db.py,sha256=mSLLxjqOxSwvMbBSYCpH9TvCvdfccWrKJx6GtkhAl8U,23881
|
|
5
|
-
ErisPulse/logger.py,sha256=ftXp4bfk0S5cnkK4wmF5WqhvuzpUL4MXsuJa-ZTBoMs,8760
|
|
6
|
-
ErisPulse/mods.py,sha256=2OgueJPetQ5N1uDr5DiFvDZ4zF1HSuZ4OsL8IFDqro8,9976
|
|
7
|
-
ErisPulse/raiserr.py,sha256=vUhJKrxwAf7ituacOZv2z2YeY4xxfMG-oLHXiDCHrBs,4176
|
|
8
|
-
ErisPulse/util.py,sha256=eXtmW39bCjbV8lxOmOro4b4gyBhKo-db_EeffJ9BDf0,4525
|
|
9
|
-
erispulse-1.2.9.dist-info/METADATA,sha256=Qf5mU81APxguKIJ36OPN8EJN45a6ofw-Gc3F2zgCLvE,6696
|
|
10
|
-
erispulse-1.2.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
-
erispulse-1.2.9.dist-info/entry_points.txt,sha256=y8ppdsQhk-azC7_ikQgRr4rITSZ4VC4crVKtzHh4TBY,146
|
|
12
|
-
erispulse-1.2.9.dist-info/licenses/LICENSE,sha256=qAe8UGD2uYa8mUPqffBkdIS_4Q5d66FlhYuo3eC_Dq8,1396
|
|
13
|
-
erispulse-1.2.9.dist-info/RECORD,,
|
|
File without changes
|