新增插件Python依赖管理系统,支持自动检查和安装依赖,优化依赖配置和错误处理,更新相关文档和示例代码。
This commit is contained in:
@@ -6,6 +6,7 @@ import toml
|
||||
import json
|
||||
import shutil
|
||||
import datetime
|
||||
from typing import Union
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.plugin_system.base.component_types import (
|
||||
@@ -42,8 +43,8 @@ class PluginBase(ABC):
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def python_dependencies(self) -> List[PythonDependency]:
|
||||
return [] # Python包依赖
|
||||
def python_dependencies(self) -> List[Union[str, PythonDependency]]:
|
||||
return [] # Python包依赖,支持字符串列表或PythonDependency对象列表
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
@@ -87,6 +88,12 @@ class PluginBase(ABC):
|
||||
self.plugin_description = self.get_manifest_info("description", "")
|
||||
self.plugin_author = self._get_author_name()
|
||||
|
||||
# 标准化Python依赖为PythonDependency对象
|
||||
normalized_python_deps = self._normalize_python_dependencies(self.python_dependencies)
|
||||
|
||||
# 检查Python依赖
|
||||
self._check_python_dependencies(normalized_python_deps)
|
||||
|
||||
# 创建插件信息对象
|
||||
self.plugin_info = PluginInfo(
|
||||
name=self.plugin_name,
|
||||
@@ -98,7 +105,7 @@ class PluginBase(ABC):
|
||||
is_built_in=False,
|
||||
config_file=self.config_file_name or "",
|
||||
dependencies=self.dependencies.copy(),
|
||||
python_dependencies=self.python_dependencies.copy(),
|
||||
python_dependencies=normalized_python_deps,
|
||||
# manifest相关信息
|
||||
manifest_data=self.manifest_data.copy(),
|
||||
license=self.get_manifest_info("license", ""),
|
||||
@@ -564,6 +571,62 @@ class PluginBase(ABC):
|
||||
|
||||
return current
|
||||
|
||||
def _normalize_python_dependencies(self, dependencies: Any) -> List[PythonDependency]:
|
||||
"""将依赖列表标准化为PythonDependency对象"""
|
||||
from packaging.requirements import Requirement
|
||||
|
||||
normalized = []
|
||||
for dep in dependencies:
|
||||
if isinstance(dep, str):
|
||||
try:
|
||||
# 尝试解析为requirement格式 (如 "package>=1.0.0")
|
||||
req = Requirement(dep)
|
||||
version_spec = str(req.specifier) if req.specifier else ""
|
||||
|
||||
normalized.append(PythonDependency(
|
||||
package_name=req.name,
|
||||
version=version_spec,
|
||||
install_name=dep # 保持原始的安装名称
|
||||
))
|
||||
except Exception:
|
||||
# 如果解析失败,作为简单包名处理
|
||||
normalized.append(PythonDependency(
|
||||
package_name=dep,
|
||||
install_name=dep
|
||||
))
|
||||
elif isinstance(dep, PythonDependency):
|
||||
normalized.append(dep)
|
||||
else:
|
||||
logger.warning(f"{self.log_prefix} 未知的依赖格式: {dep}")
|
||||
|
||||
return normalized
|
||||
|
||||
def _check_python_dependencies(self, dependencies: List[PythonDependency]) -> bool:
|
||||
"""检查Python依赖并尝试自动安装"""
|
||||
if not dependencies:
|
||||
logger.info(f"{self.log_prefix} 无Python依赖需要检查")
|
||||
return True
|
||||
|
||||
try:
|
||||
# 延迟导入以避免循环依赖
|
||||
from src.plugin_system.utils.dependency_manager import get_dependency_manager
|
||||
|
||||
dependency_manager = get_dependency_manager()
|
||||
success, errors = dependency_manager.check_and_install_dependencies(dependencies, self.plugin_name)
|
||||
|
||||
if success:
|
||||
logger.info(f"{self.log_prefix} Python依赖检查通过")
|
||||
return True
|
||||
else:
|
||||
logger.error(f"{self.log_prefix} Python依赖检查失败:")
|
||||
for error in errors:
|
||||
logger.error(f"{self.log_prefix} - {error}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} Python依赖检查时发生异常: {e}", exc_info=True)
|
||||
return False
|
||||
|
||||
@abstractmethod
|
||||
def register_plugin(self) -> bool:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user