ErisPulse 1.2.8__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/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,137 +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] | 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] | None:
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 None
115
- return {
116
- "type": name,
117
- "doc": getattr(err_cls, "__doc__", ""),
118
- "class": err_cls,
119
- }
120
-
121
- raiserr = Error()
122
-
123
- # 全局异常处理器
124
- def global_exception_handler(exc_type, exc_value, exc_traceback):
125
- error_message = ''.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
126
- raiserr.ExternalError(
127
- f"{exc_type.__name__}: {exc_value}\nTraceback:\n{error_message}"
128
- )
129
- def async_exception_handler(loop, context):
130
- exception = context.get('exception')
131
- tb = ''.join(traceback.format_exception(type(exception), exception, exception.__traceback__))
132
- raiserr.ExternalError(
133
- f"{type(exception).__name__}: {exception}\nTraceback:\n{tb}"
134
- )
135
-
136
- sys.excepthook = global_exception_handler
137
- 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
@@ -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=6txXLfHmC9hb-HI1mbSMxaz1H0T4dfXGSrENRZ06AVg,4081
8
- ErisPulse/util.py,sha256=eXtmW39bCjbV8lxOmOro4b4gyBhKo-db_EeffJ9BDf0,4525
9
- erispulse-1.2.8.dist-info/METADATA,sha256=nPXMDvBfN44juOQLFQ8eFDBU87ZBy1xEFP8c9nIM8gQ,6696
10
- erispulse-1.2.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
- erispulse-1.2.8.dist-info/entry_points.txt,sha256=y8ppdsQhk-azC7_ikQgRr4rITSZ4VC4crVKtzHh4TBY,146
12
- erispulse-1.2.8.dist-info/licenses/LICENSE,sha256=qAe8UGD2uYa8mUPqffBkdIS_4Q5d66FlhYuo3eC_Dq8,1396
13
- erispulse-1.2.8.dist-info/RECORD,,