From da0f68491d8c7d1f208719409f893080dc4db799 Mon Sep 17 00:00:00 2001 From: Ian Anderson Date: Fri, 24 Oct 2025 15:26:03 -0700 Subject: [PATCH 1/2] Replace urllib.request.urlretrieve with requests library The current implementation using urllib.request.urlretrieve doesn't properly handle HuggingFace redirect responses, which can cause download failures when fetching model weights and data files. This change replaces those calls with a new download_file_with_progress function that uses the requests library with proper redirect handling (allow_redirects=True) and streaming support. --- src/boltz/main.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/boltz/main.py b/src/boltz/main.py index 4a3750fec..4dfa4035b 100644 --- a/src/boltz/main.py +++ b/src/boltz/main.py @@ -194,6 +194,27 @@ def download_boltz1(cache: Path) -> None: continue +def download_file_with_progress(url: str, dest_path: str) -> None: + """Download a file from url to dest_path with proper redirect handling. + + Uses requests instead of urllib to properly handle HuggingFace redirects. + + Parameters + ---------- + url : str + The URL to download from. + dest_path : str + The destination file path. + """ + response = requests.get(url, stream=True, allow_redirects=True, timeout=300) + response.raise_for_status() + + with open(dest_path, 'wb') as f: + for chunk in response.iter_content(chunk_size=8192): + if chunk: + f.write(chunk) + + @rank_zero_only def download_boltz2(cache: Path) -> None: """Download all the required data. @@ -213,7 +234,7 @@ def download_boltz2(cache: Path) -> None: "This may take a bit of time. You may change the cache directory " "with the --cache flag." ) - urllib.request.urlretrieve(MOL_URL, str(tar_mols)) # noqa: S310 + download_file_with_progress(MOL_URL, str(tar_mols)) if not mols.exists(): click.echo( f"Extracting the CCD data to {mols}. " @@ -232,7 +253,7 @@ def download_boltz2(cache: Path) -> None: ) for i, url in enumerate(BOLTZ2_URL_WITH_FALLBACK): try: - urllib.request.urlretrieve(url, str(model)) # noqa: S310 + download_file_with_progress(url, str(model)) break except Exception as e: # noqa: BLE001 if i == len(BOLTZ2_URL_WITH_FALLBACK) - 1: @@ -249,7 +270,7 @@ def download_boltz2(cache: Path) -> None: ) for i, url in enumerate(BOLTZ2_AFFINITY_URL_WITH_FALLBACK): try: - urllib.request.urlretrieve(url, str(affinity_model)) # noqa: S310 + download_file_with_progress(url, str(affinity_model)) break except Exception as e: # noqa: BLE001 if i == len(BOLTZ2_AFFINITY_URL_WITH_FALLBACK) - 1: From 3d00c0e8ebc3b02d96a130389af663a1c6e9fd23 Mon Sep 17 00:00:00 2001 From: Ian Anderson Date: Fri, 24 Oct 2025 15:34:28 -0700 Subject: [PATCH 2/2] Add requests import --- src/boltz/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/boltz/main.py b/src/boltz/main.py index 4dfa4035b..aef771d85 100644 --- a/src/boltz/main.py +++ b/src/boltz/main.py @@ -12,6 +12,7 @@ from typing import Literal, Optional import click +import requests import torch from pytorch_lightning import Trainer, seed_everything from pytorch_lightning.strategies import DDPStrategy