mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 09:50:21 +08:00
chore: 升级到 Python 3.14 并现代化代码
- 升级 Docker 基础镜像从 Python 3.12 到 3.14 - 更新 pyproject.toml 支持 Python 3.13/3.14 - 移除 Python 3.8/3.9/3.10/3.11 分类器 - 更新 black 和 mypy 配置目标版本 - 将 get_event_loop() 替换为 get_running_loop() 加上 RuntimeError 处理 - 简化 compute_cost_sync 中的 asyncio.run 使用 - Dict/List/Tuple/Set → dict/list/tuple/set (PEP 585) - Optional[T] → T | None (PEP 604) - Union[A, B] → A | B (PEP 604) - 移除废弃的 typing 导入 - 移除不必要的字符串引号注解
This commit is contained in:
@@ -6,7 +6,10 @@
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING, Any, Awaitable, Callable, List, Optional, Tuple
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from collections.abc import Callable
|
||||
from collections.abc import Awaitable
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fastapi import APIRouter
|
||||
@@ -50,16 +53,16 @@ class ModuleMetadata:
|
||||
# 可用性控制(部署级)
|
||||
env_key: str # 环境变量名: LDAP_AVAILABLE
|
||||
default_available: bool = False # 默认是否可用
|
||||
required_packages: List[str] = field(default_factory=list) # 依赖的 Python 包
|
||||
dependencies: List[str] = field(default_factory=list) # 依赖的其他模块
|
||||
required_packages: list[str] = field(default_factory=list) # 依赖的 Python 包
|
||||
dependencies: list[str] = field(default_factory=list) # 依赖的其他模块
|
||||
|
||||
# 路由配置 - 模块自定义前缀
|
||||
api_prefix: Optional[str] = None # 如 "/api/admin/ldap"
|
||||
api_prefix: str | None = None # 如 "/api/admin/ldap"
|
||||
|
||||
# 前端配置
|
||||
admin_route: Optional[str] = None # 管理页面路由: "/admin/ldap"
|
||||
admin_menu_icon: Optional[str] = None # 菜单图标
|
||||
admin_menu_group: Optional[str] = None # 菜单分组: "system", "security"
|
||||
admin_route: str | None = None # 管理页面路由: "/admin/ldap"
|
||||
admin_menu_icon: str | None = None # 菜单图标
|
||||
admin_menu_group: str | None = None # 菜单分组: "system", "security"
|
||||
admin_menu_order: int = 100 # 菜单排序(越小越靠前)
|
||||
|
||||
|
||||
@@ -74,19 +77,19 @@ class ModuleDefinition:
|
||||
metadata: ModuleMetadata
|
||||
|
||||
# 工厂函数 - 内部再 import 重依赖
|
||||
router_factory: Optional[Callable[[], "APIRouter"]] = None
|
||||
service_factory: Optional[Callable[[], Any]] = None
|
||||
router_factory: Callable[[], APIRouter] | None = None
|
||||
service_factory: Callable[[], Any] | None = None
|
||||
|
||||
# 生命周期钩子
|
||||
on_startup: Optional[Callable[[], Awaitable[None]]] = None
|
||||
on_shutdown: Optional[Callable[[], Awaitable[None]]] = None
|
||||
health_check: Optional[Callable[[], Awaitable[ModuleHealth]]] = None
|
||||
on_startup: Callable[[], Awaitable[None]] | None = None
|
||||
on_shutdown: Callable[[], Awaitable[None]] | None = None
|
||||
health_check: Callable[[], Awaitable[ModuleHealth]] | None = None
|
||||
|
||||
# 自定义依赖检测(可选,用于检测 ldap3 等库是否安装)
|
||||
check_dependencies: Optional[Callable[[], bool]] = None
|
||||
check_dependencies: Callable[[], bool] | None = None
|
||||
|
||||
# 配置验证(可选,启用模块时调用,返回 (success, error_message))
|
||||
validate_config: Optional[Callable[["Session"], Tuple[bool, str]]] = None
|
||||
validate_config: Callable[[Session], tuple[bool, str]] | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -102,7 +105,7 @@ class ModuleStatus:
|
||||
enabled: bool # 运行级启用(数据库配置)
|
||||
active: bool # 最终激活状态 (available && enabled && dependencies_ok)
|
||||
config_validated: bool # 配置验证通过(只有验证通过才允许启用)
|
||||
config_error: Optional[str] # 配置验证失败的错误信息
|
||||
config_error: str | None # 配置验证失败的错误信息
|
||||
|
||||
# 显示信息
|
||||
display_name: str
|
||||
@@ -110,9 +113,9 @@ class ModuleStatus:
|
||||
category: ModuleCategory
|
||||
|
||||
# 前端配置
|
||||
admin_route: Optional[str]
|
||||
admin_menu_icon: Optional[str]
|
||||
admin_menu_group: Optional[str]
|
||||
admin_route: str | None
|
||||
admin_menu_icon: str | None
|
||||
admin_menu_group: str | None
|
||||
admin_menu_order: int
|
||||
|
||||
# 健康状态
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
负责模块的注册、状态管理和生命周期控制
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Set
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from src.core.logger import logger
|
||||
from src.core.modules.base import (
|
||||
@@ -31,14 +33,14 @@ class ModuleRegistry:
|
||||
- 提供模块状态查询
|
||||
"""
|
||||
|
||||
_instance: Optional["ModuleRegistry"] = None
|
||||
_instance: ModuleRegistry | None = None
|
||||
|
||||
def __init__(self):
|
||||
self._modules: Dict[str, ModuleDefinition] = {}
|
||||
self._initialized: Set[str] = set()
|
||||
self._modules: dict[str, ModuleDefinition] = {}
|
||||
self._initialized: set[str] = set()
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls) -> "ModuleRegistry":
|
||||
def get_instance(cls) -> ModuleRegistry:
|
||||
"""获取单例实例"""
|
||||
if cls._instance is None:
|
||||
cls._instance = cls()
|
||||
@@ -63,11 +65,11 @@ class ModuleRegistry:
|
||||
self._modules[name] = module
|
||||
logger.debug(f"Module [{name}] registered")
|
||||
|
||||
def get_module(self, name: str) -> Optional[ModuleDefinition]:
|
||||
def get_module(self, name: str) -> ModuleDefinition | None:
|
||||
"""获取模块定义"""
|
||||
return self._modules.get(name)
|
||||
|
||||
def get_all_modules(self) -> List[ModuleDefinition]:
|
||||
def get_all_modules(self) -> list[ModuleDefinition]:
|
||||
"""获取所有已注册模块"""
|
||||
return list(self._modules.values())
|
||||
|
||||
@@ -115,13 +117,13 @@ class ModuleRegistry:
|
||||
|
||||
return True
|
||||
|
||||
def get_available_modules(self) -> List[ModuleDefinition]:
|
||||
def get_available_modules(self) -> list[ModuleDefinition]:
|
||||
"""获取所有部署可用的模块"""
|
||||
return [m for m in self._modules.values() if self.is_available(m.metadata.name)]
|
||||
|
||||
# ========== 启用状态检查(运行级)==========
|
||||
|
||||
def is_enabled(self, name: str, db: "Session") -> bool:
|
||||
def is_enabled(self, name: str, db: Session) -> bool:
|
||||
"""
|
||||
检查模块是否运行启用(数据库配置)
|
||||
|
||||
@@ -135,7 +137,7 @@ class ModuleRegistry:
|
||||
value = SystemConfigService.get_config(db, config_key, default=False)
|
||||
return bool(value)
|
||||
|
||||
def set_enabled(self, name: str, enabled: bool, db: "Session") -> None:
|
||||
def set_enabled(self, name: str, enabled: bool, db: Session) -> None:
|
||||
"""
|
||||
设置模块启用状态
|
||||
|
||||
@@ -156,7 +158,7 @@ class ModuleRegistry:
|
||||
|
||||
# ========== 激活状态检查 ==========
|
||||
|
||||
def is_active(self, name: str, db: "Session") -> bool:
|
||||
def is_active(self, name: str, db: Session) -> bool:
|
||||
"""
|
||||
检查模块是否最终激活
|
||||
|
||||
@@ -177,7 +179,7 @@ class ModuleRegistry:
|
||||
|
||||
# ========== 配置验证 ==========
|
||||
|
||||
def validate_config(self, name: str, db: "Session") -> tuple[bool, str]:
|
||||
def validate_config(self, name: str, db: Session) -> tuple[bool, str]:
|
||||
"""
|
||||
验证模块配置是否有效
|
||||
|
||||
@@ -206,8 +208,8 @@ class ModuleRegistry:
|
||||
# ========== 状态查询 ==========
|
||||
|
||||
def get_module_status(
|
||||
self, name: str, db: "Session", health: Optional[ModuleHealth] = None
|
||||
) -> Optional[ModuleStatus]:
|
||||
self, name: str, db: Session, health: ModuleHealth | None = None
|
||||
) -> ModuleStatus | None:
|
||||
"""
|
||||
获取单个模块状态
|
||||
|
||||
@@ -225,7 +227,7 @@ class ModuleRegistry:
|
||||
|
||||
# 获取配置验证状态
|
||||
config_validated = False
|
||||
config_error: Optional[str] = None
|
||||
config_error: str | None = None
|
||||
if available:
|
||||
config_validated, config_error = self.validate_config(name, db)
|
||||
if config_validated:
|
||||
@@ -279,8 +281,8 @@ class ModuleRegistry:
|
||||
return ModuleHealth.UNHEALTHY
|
||||
|
||||
async def get_module_status_async(
|
||||
self, name: str, db: "Session"
|
||||
) -> Optional[ModuleStatus]:
|
||||
self, name: str, db: Session
|
||||
) -> ModuleStatus | None:
|
||||
"""异步获取模块状态(包含健康检查)"""
|
||||
if name not in self._modules:
|
||||
return None
|
||||
@@ -288,7 +290,7 @@ class ModuleRegistry:
|
||||
health = await self.check_health(name) if self.is_available(name) else ModuleHealth.UNKNOWN
|
||||
return self.get_module_status(name, db, health=health)
|
||||
|
||||
async def get_all_status_async(self, db: "Session") -> Dict[str, ModuleStatus]:
|
||||
async def get_all_status_async(self, db: Session) -> dict[str, ModuleStatus]:
|
||||
"""异步获取所有模块状态(包含健康检查)"""
|
||||
result = {}
|
||||
for name in self._modules:
|
||||
@@ -297,7 +299,7 @@ class ModuleRegistry:
|
||||
result[name] = status
|
||||
return result
|
||||
|
||||
def get_all_status(self, db: "Session") -> Dict[str, ModuleStatus]:
|
||||
def get_all_status(self, db: Session) -> dict[str, ModuleStatus]:
|
||||
"""获取所有模块状态(同步版本,不含健康检查)"""
|
||||
result = {}
|
||||
for name in self._modules:
|
||||
@@ -306,7 +308,7 @@ class ModuleRegistry:
|
||||
result[name] = status
|
||||
return result
|
||||
|
||||
def get_available_status(self, db: "Session") -> Dict[str, ModuleStatus]:
|
||||
def get_available_status(self, db: Session) -> dict[str, ModuleStatus]:
|
||||
"""获取所有可用模块的状态"""
|
||||
result = {}
|
||||
for name, module in self._modules.items():
|
||||
@@ -316,7 +318,7 @@ class ModuleRegistry:
|
||||
result[name] = status
|
||||
return result
|
||||
|
||||
def get_auth_modules_status(self, db: "Session") -> List[ModuleStatus]:
|
||||
def get_auth_modules_status(self, db: Session) -> list[ModuleStatus]:
|
||||
"""获取认证模块状态(供登录页使用)"""
|
||||
result = []
|
||||
for name, module in self._modules.items():
|
||||
|
||||
Reference in New Issue
Block a user