|
1 | 1 | #!/usr/bin/env python3 |
2 | 2 | # -*- coding: utf-8 -*- |
3 | | -import asyncio |
4 | 3 | import inspect |
5 | 4 | import os |
6 | 5 | import subprocess |
7 | 6 | import sys |
8 | 7 | import warnings |
9 | 8 |
|
10 | | -from asyncio import subprocess as async_subprocess |
11 | | - |
12 | 9 | import rtoml |
13 | 10 |
|
14 | 11 | from fastapi import APIRouter |
| 12 | +from starlette.concurrency import run_in_threadpool |
15 | 13 |
|
16 | 14 | from backend.core.conf import settings |
17 | 15 | from backend.core.path_conf import PLUGIN_DIR |
@@ -156,49 +154,19 @@ def install_requirements() -> None: |
156 | 154 | continue |
157 | 155 | else: |
158 | 156 | try: |
159 | | - subprocess.run([sys.executable, '-m', 'ensurepip', '--upgrade']) |
160 | | - pip_requirements = [sys.executable, '-m', 'pip', 'install', '-r', requirements_file] |
| 157 | + ensurepip_install = [sys.executable, '-m', 'ensurepip', '--upgrade'] |
| 158 | + pip_install = [sys.executable, '-m', 'pip', 'install', '-r', requirements_file] |
161 | 159 | if settings.PLUGIN_PIP_CHINA: |
162 | | - pip_requirements.extend(['-i', settings.PLUGIN_PIP_INDEX_URL]) |
163 | | - subprocess.check_call(pip_requirements) |
| 160 | + pip_install.extend(['-i', settings.PLUGIN_PIP_INDEX_URL]) |
| 161 | + subprocess.check_call(ensurepip_install) |
| 162 | + subprocess.check_call(pip_install) |
164 | 163 | except subprocess.CalledProcessError as e: |
165 | | - raise PluginInjectError(f'插件 {plugin} 依赖安装失败:{e}') from e |
| 164 | + raise PluginInjectError(f'插件 {plugin} 依赖安装失败:{e.stderr}') from e |
166 | 165 |
|
167 | 166 |
|
168 | | -async def install_requirements_async(wait: bool = True) -> None: |
| 167 | +async def install_requirements_async() -> None: |
169 | 168 | """ |
170 | | - 异步安装插件依赖 |
171 | | -
|
172 | | - :param wait: 是否等待结果并校验,开启将造成 IO 阻塞 |
173 | | - :return: |
| 169 | + 异步安装插件依赖(由于 Windows 平台限制,无法实现完美的全异步方案),详情: |
| 170 | + https://stackoverflow.com/questions/44633458/why-am-i-getting-notimplementederror-with-async-and-await-on-windows |
174 | 171 | """ |
175 | | - plugins = get_plugins() |
176 | | - for plugin in plugins: |
177 | | - requirements_file = os.path.join(PLUGIN_DIR, plugin, 'requirements.txt') |
178 | | - if not os.path.exists(requirements_file): |
179 | | - continue |
180 | | - else: |
181 | | - ensurepip_process = await async_subprocess.create_subprocess_exec( |
182 | | - sys.executable, |
183 | | - '-m', |
184 | | - 'ensurepip', |
185 | | - '--upgrade', |
186 | | - stdout=asyncio.subprocess.PIPE, |
187 | | - stderr=asyncio.subprocess.PIPE, |
188 | | - ) |
189 | | - if wait: |
190 | | - _, ensurepip_stderr = await ensurepip_process.communicate() |
191 | | - if ensurepip_process.returncode != 0: |
192 | | - raise PluginInjectError(f'ensurepip 安装失败:{ensurepip_stderr}') |
193 | | - pip_requirements = [sys.executable, '-m', 'pip', 'install', '-r', requirements_file] |
194 | | - if settings.PLUGIN_PIP_CHINA: |
195 | | - pip_requirements.extend(['-i', settings.PLUGIN_PIP_INDEX_URL]) |
196 | | - pip_process = await async_subprocess.create_subprocess_exec( |
197 | | - *pip_requirements, |
198 | | - stdout=asyncio.subprocess.PIPE, |
199 | | - stderr=asyncio.subprocess.PIPE, |
200 | | - ) |
201 | | - if wait: |
202 | | - _, pip_stderr = await pip_process.communicate() |
203 | | - if pip_process.returncode != 0: |
204 | | - raise PluginInjectError(f'插件 {plugin} 依赖包安装失败:{pip_stderr}') |
| 172 | + await run_in_threadpool(install_requirements) |
0 commit comments