diff --git a/homeassistant/requirements.py b/homeassistant/requirements.py index 718ceba54ab..67d0ede96bc 100644 --- a/homeassistant/requirements.py +++ b/homeassistant/requirements.py @@ -14,6 +14,7 @@ import homeassistant.util.package as pkg_util # mypy: disallow-any-generics +PIP_TIMEOUT = 60 # The default is too low when the internet connection is satellite or high latency DATA_PIP_LOCK = "pip_lock" DATA_PKG_CACHE = "pkg_cache" DATA_INTEGRATIONS_WITH_REQS = "integrations_with_reqs" @@ -169,6 +170,7 @@ def pip_kwargs(config_dir: str | None) -> dict[str, Any]: kwargs = { "constraints": os.path.join(os.path.dirname(__file__), CONSTRAINT_FILE), "no_cache_dir": is_docker, + "timeout": PIP_TIMEOUT, } if "WHEELS_LINKS" in os.environ: kwargs["find_links"] = os.environ["WHEELS_LINKS"] diff --git a/homeassistant/util/package.py b/homeassistant/util/package.py index 50d46b6c469..609d09e4f55 100644 --- a/homeassistant/util/package.py +++ b/homeassistant/util/package.py @@ -63,6 +63,7 @@ def install_package( target: str | None = None, constraints: str | None = None, find_links: str | None = None, + timeout: int | None = None, no_cache_dir: bool | None = False, ) -> bool: """Install a package on PyPi. Accepts pip compatible package strings. @@ -73,6 +74,8 @@ def install_package( _LOGGER.info("Attempting install of %s", package) env = os.environ.copy() args = [sys.executable, "-m", "pip", "install", "--quiet", package] + if timeout: + args += ["--timeout", str(timeout)] if no_cache_dir: args.append("--no-cache-dir") if upgrade: diff --git a/tests/test_requirements.py b/tests/test_requirements.py index 26f3603910d..82ce10872bf 100644 --- a/tests/test_requirements.py +++ b/tests/test_requirements.py @@ -38,6 +38,7 @@ async def test_requirement_installed_in_venv(hass): assert mock_install.call_args == call( "package==0.0.1", constraints=os.path.join("ha_package_path", CONSTRAINT_FILE), + timeout=60, no_cache_dir=False, ) @@ -59,6 +60,7 @@ async def test_requirement_installed_in_deps(hass): "package==0.0.1", target=hass.config.path("deps"), constraints=os.path.join("ha_package_path", CONSTRAINT_FILE), + timeout=60, no_cache_dir=False, ) @@ -304,6 +306,7 @@ async def test_install_with_wheels_index(hass): "hello==1.0.0", find_links="https://wheels.hass.io/test", constraints=os.path.join("ha_package_path", CONSTRAINT_FILE), + timeout=60, no_cache_dir=True, ) @@ -327,6 +330,7 @@ async def test_install_on_docker(hass): assert mock_inst.call_args == call( "hello==1.0.0", constraints=os.path.join("ha_package_path", CONSTRAINT_FILE), + timeout=60, no_cache_dir=True, )