|
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