From 09248352538c1a627b94ee4ac9dd2365daae26b8 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sat, 31 May 2025 11:44:58 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E5=B0=86=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E6=A3=80=E6=9F=A5=E5=92=8C=20pip=20=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E6=96=B9=E6=B3=95=E6=94=B9=E4=B8=BA=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E6=8F=90=E9=AB=98=E6=80=A7=E8=83=BD=E5=92=8C?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E9=80=9F=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/star/star_manager.py | 6 +++--- astrbot/core/utils/pip_installer.py | 33 ++++++++++++++++++++++------- astrbot/dashboard/routes/update.py | 4 ++-- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py index ff07de712..44e018dfc 100644 --- a/astrbot/core/star/star_manager.py +++ b/astrbot/core/star/star_manager.py @@ -166,7 +166,7 @@ class PluginManager: plugins.extend(_p) return plugins - def _check_plugin_dept_update(self, target_plugin: str = None): + async def _check_plugin_dept_update(self, target_plugin: str = None): """检查插件的依赖 如果 target_plugin 为 None,则检查所有插件的依赖 """ @@ -185,7 +185,7 @@ class PluginManager: pth = os.path.join(plugin_path, "requirements.txt") logger.info(f"正在安装插件 {p} 所需的依赖库: {pth}") try: - pip_installer.install(requirements_path=pth) + await pip_installer.install(requirements_path=pth) except Exception as e: logger.error(f"更新插件 {p} 的依赖失败。Code: {str(e)}") @@ -407,7 +407,7 @@ class PluginManager: module = __import__(path, fromlist=[module_str]) except (ModuleNotFoundError, ImportError): # 尝试安装依赖 - self._check_plugin_dept_update(target_plugin=root_dir_name) + await self._check_plugin_dept_update(target_plugin=root_dir_name) module = __import__(path, fromlist=[module_str]) except Exception as e: logger.error(traceback.format_exc()) diff --git a/astrbot/core/utils/pip_installer.py b/astrbot/core/utils/pip_installer.py index 0163b11b4..13bdbad6a 100644 --- a/astrbot/core/utils/pip_installer.py +++ b/astrbot/core/utils/pip_installer.py @@ -1,5 +1,5 @@ import logging -from pip import main as pip_main +import asyncio logger = logging.getLogger("astrbot") @@ -9,7 +9,7 @@ class PipInstaller: self.pip_install_arg = pip_install_arg self.pypi_index_url = pypi_index_url - def install( + async def install( self, package_name: str = None, requirements_path: str = None, @@ -29,12 +29,29 @@ class PipInstaller: args.extend(self.pip_install_arg.split()) logger.info(f"Pip 包管理器: pip {' '.join(args)}") + try: + process = await asyncio.create_subprocess_exec( + "pip", *args, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.STDOUT, + ) - result_code = pip_main(args) + assert process.stdout is not None + async for line in process.stdout: + logger.info(line.decode().strip()) - # 清除 pip.main 导致的多余的 logging handlers - for handler in logging.root.handlers[:]: - logging.root.removeHandler(handler) + await process.wait() - if result_code != 0: - raise Exception(f"安装失败,错误码:{result_code}") + if process.returncode != 0: + raise Exception(f"安装失败,错误码:{process.returncode}") + except FileNotFoundError: + # 没有 pip + from pip import main as pip_main + result_code = pip_main(args) + + # 清除 pip.main 导致的多余的 logging handlers + for handler in logging.root.handlers[:]: + logging.root.removeHandler(handler) + + if result_code != 0: + raise Exception(f"安装失败,错误码:{result_code}") diff --git a/astrbot/dashboard/routes/update.py b/astrbot/dashboard/routes/update.py index 44adf2591..f88e9a208 100644 --- a/astrbot/dashboard/routes/update.py +++ b/astrbot/dashboard/routes/update.py @@ -91,7 +91,7 @@ class UpdateRoute(Route): # pip 更新依赖 logger.info("更新依赖中...") try: - pip_installer.install(requirements_path="requirements.txt") + await pip_installer.install(requirements_path="requirements.txt") except Exception as e: logger.error(f"更新依赖失败: {e}") @@ -140,7 +140,7 @@ class UpdateRoute(Route): if not package: return Response().error("缺少参数 package 或不合法。").__dict__ try: - pip_installer.install(package, mirror=mirror) + await pip_installer.install(package, mirror=mirror) return Response().ok(None, "安装成功。").__dict__ except Exception as e: logger.error(f"/api/update_pip: {traceback.format_exc()}") From 18f919fb6b666fdcc438a0757ae258bb17a5b6b3 Mon Sep 17 00:00:00 2001 From: Soulter <37870767+Soulter@users.noreply.github.com> Date: Sat, 31 May 2025 11:47:29 +0800 Subject: [PATCH 2/2] perf: pip_main wrapped in asyncio.to_thread Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- astrbot/core/utils/pip_installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/astrbot/core/utils/pip_installer.py b/astrbot/core/utils/pip_installer.py index 13bdbad6a..a7c04d3d9 100644 --- a/astrbot/core/utils/pip_installer.py +++ b/astrbot/core/utils/pip_installer.py @@ -47,7 +47,7 @@ class PipInstaller: except FileNotFoundError: # 没有 pip from pip import main as pip_main - result_code = pip_main(args) + result_code = await asyncio.to_thread(pip_main, args) # 清除 pip.main 导致的多余的 logging handlers for handler in logging.root.handlers[:]: