← Files PixVerseARCHIVED FILE
pvx/python_dependencies.py
2.13 KB · Oct 8, 2026 · 12:02 UTC
"""Install rendering dependencies in a private, interpreter-specific runtime."""
from __future__ import annotations
import importlib
import subprocess
import sys
import sysconfig
from pathlib import Path
from .shell import run
from .state import local_data_home
class PythonDependencyError(RuntimeError):
pass
def python_packages_path() -> Path:
tag = f"{sys.implementation.cache_tag}-{sysconfig.get_platform()}"
return local_data_home() / "runtime" / "python" / tag / "site-packages"
def pillow_status() -> dict:
target = python_packages_path()
if target.is_dir() and str(target) not in sys.path:
sys.path.insert(0, str(target))
importlib.invalidate_caches()
try:
pillow = importlib.import_module("PIL.Image")
except ImportError:
return {"found": False, "ok": False, "python": sys.executable, "runtime": str(target)}
return {"found": True, "ok": True, "version": pillow.__version__, "python": sys.executable,
"runtime": str(target)}
def ensure_pillow() -> dict:
status = pillow_status()
if status["ok"]:
return status
target = python_packages_path()
target.mkdir(parents=True, exist_ok=True)
command = [sys.executable, "-m", "pip", "install", "--disable-pip-version-check",
"--target", str(target), "--only-binary=:all:", "--upgrade", "Pillow"]
print("Installing Pillow in the plugin-managed Python runtime...", file=sys.stderr)
try:
result = run(command, timeout=300)
except subprocess.TimeoutExpired as exc:
raise PythonDependencyError("Pillow installation timed out after 300 seconds; retry bootstrap --yes.") from exc
if not result.ok:
raise PythonDependencyError(
"Pillow wheel installation failed. Check pip, network access and wheel support for this Python/platform; "
"source builds are disabled. "
+ (result.stderr or result.stdout)[-1200:]
)
importlib.invalidate_caches()
status = pillow_status()
if not status["ok"]:
raise PythonDependencyError("Pillow installation completed but import failed; retry bootstrap --yes.")
return status
SHA-256: 050fa040f8e18192aba4c1681a7a20a6315cbad06f59d2c87568077b38cf1ae4