Fallback to standard pip for package installs (#2316)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Sun, 10 Aug 2025 19:08:48 +0000 (21:08 +0200)
committerGitHub <noreply@github.com>
Sun, 10 Aug 2025 19:08:48 +0000 (21:08 +0200)
music_assistant/helpers/util.py

index 4a3238a19fefa82445a8ab8a80ba13fdf264dd7e..f24d6051d26fbcf78ce175c07272131e149fa73a 100644 (file)
@@ -424,15 +424,16 @@ def empty_queue[T](q: asyncio.Queue[T]) -> None:
             pass
 
 
-async def install_package(package: str) -> None:
+async def install_package(package: str, prefer_uv: bool = True) -> None:
     """Install package with pip, raise when install failed."""
     LOGGER.debug("Installing python package %s", package)
-    args = ["uv", "pip", "install", "--no-cache", "--find-links", HA_WHEELS, package]
-    return_code, output = await check_output(*args)
-
-    if return_code != 0 and "Permission denied" in output.decode():
-        # try again with regular pip
-        # uv pip seems to have issues with permissions on docker installs
+    if await get_package_version("uv") is None:
+        # uv is not present on this system
+        prefer_uv = False
+    # determine args (either uv pip or regular pip)
+    if prefer_uv:
+        args = ["uv", "pip", "install", "--no-cache", "--find-links", HA_WHEELS, package]
+    else:
         args = [
             "pip",
             "install",
@@ -442,9 +443,13 @@ async def install_package(package: str) -> None:
             HA_WHEELS,
             package,
         ]
-        return_code, output = await check_output(*args)
-
+    return_code, output = await check_output(*args)
     if return_code != 0:
+        if "Permission denied" in output.decode() and prefer_uv:
+            # try again with regular pip
+            # uv pip seems to have issues with permissions on docker installs
+            await install_package(package, prefer_uv=False)
+            return
         msg = f"Failed to install package {package}\n{output.decode()}"
         raise RuntimeError(msg)