diff --git a/backend/plugin/requirements.py b/backend/plugin/requirements.py index c67d760c..adf1b6b8 100644 --- a/backend/plugin/requirements.py +++ b/backend/plugin/requirements.py @@ -1,6 +1,5 @@ import os import subprocess -import sys from importlib.metadata import PackageNotFoundError, distribution @@ -15,61 +14,6 @@ class PluginInstallError(Exception): """插件安装错误""" -def _ensure_pip_available() -> bool: - """确保 pip 在虚拟环境中可用""" - try: - result = subprocess.run([sys.executable, '-m', 'pip', '--version'], capture_output=True, text=True) - if result.returncode == 0: - return True - except (subprocess.TimeoutExpired, subprocess.SubprocessError, FileNotFoundError): - pass - - # 尝试使用 ensurepip - try: - subprocess.check_call( - [sys.executable, '-m', 'ensurepip', '--default-pip'], - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - ) - result = subprocess.run([sys.executable, '-m', 'pip', '--version'], capture_output=True, text=True) - if result.returncode == 0: - return True - except (subprocess.CalledProcessError, subprocess.TimeoutExpired, subprocess.SubprocessError, FileNotFoundError): - pass - - # 尝试下载并安装 - try: - import os - import tempfile - - import httpx - - try: - with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f: - with httpx.Client(timeout=3) as client: - get_pip_url = 'https://bootstrap.pypa.io/get-pip.py' - response = client.get(get_pip_url) - response.raise_for_status() - f.write(response.text) - temp_file = f.name - except Exception: # noqa: ignore - return False - - try: - subprocess.check_call([sys.executable, temp_file], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - result = subprocess.run([sys.executable, '-m', 'pip', '--version'], capture_output=True, text=True) - return result.returncode == 0 - finally: - try: - os.unlink(temp_file) - except OSError: - pass - except Exception: # noqa: ignore - pass - - return False - - def get_plugins() -> list[str]: """ 获取插件列表 @@ -111,10 +55,7 @@ def install_requirements(plugin: str | None) -> None: # noqa: C901 if missing_dependencies: try: - if not _ensure_pip_available(): - raise PluginInstallError(f'pip 安装失败,无法继续安装插件 {plugin} 依赖') - - pip_install = [sys.executable, '-m', 'pip', 'install', '-r', requirements_file] + pip_install = ['uv', 'pip', 'install', '-r', requirements_file] if settings.PLUGIN_PIP_CHINA: pip_install.extend(['-i', settings.PLUGIN_PIP_INDEX_URL]) @@ -149,7 +90,7 @@ def uninstall_requirements(plugin: str) -> None: requirements_file = PLUGIN_DIR / plugin / 'requirements.txt' if os.path.exists(requirements_file): try: - pip_uninstall = [sys.executable, '-m', 'pip', 'uninstall', '-r', requirements_file, '-y'] + pip_uninstall = ['uv', 'pip', 'uninstall', '-r', str(requirements_file), '-y'] subprocess.check_call(pip_uninstall, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) except subprocess.CalledProcessError as e: raise PluginInstallError(f'插件 {plugin} 依赖卸载失败:{e}') from e