Use explicit download errors for factor loader fallback

This commit is contained in:
2026-04-07 16:01:51 +08:00
parent c46727b1ca
commit 7f0c5de574
2 changed files with 29 additions and 30 deletions

View File

@@ -1,6 +1,8 @@
from __future__ import annotations
import io
import socket
import ssl
import warnings
import zipfile
from pathlib import Path
@@ -21,13 +23,20 @@ class ExternalFactorFormatError(ValueError):
pass
class ExternalFactorDownloadError(OSError):
pass
def _download_kf_zip_bytes() -> bytes:
request = Request(
KEN_FRENCH_DAILY_FF5_ZIP_URL,
headers={"User-Agent": "quant-factor-attribution/0.1"},
)
with urlopen(request, timeout=30) as response:
return response.read()
try:
with urlopen(request, timeout=30) as response:
return response.read()
except (URLError, TimeoutError, ConnectionError, socket.timeout, ssl.SSLError) as exc:
raise ExternalFactorDownloadError(f"Failed to download external factor data: {exc}") from exc
def _parse_kf_daily_csv(raw_bytes: bytes) -> pd.DataFrame:
@@ -99,7 +108,7 @@ def load_external_us_factors(cache_dir: Path | str = "data/factors") -> pd.DataF
try:
raw_bytes = _download_kf_zip_bytes()
except (URLError, TimeoutError, ConnectionError, OSError) as exc:
except ExternalFactorDownloadError as exc:
if cache_path.exists():
return _warn_and_load_cached_factors(cache_path, f"download failed: {exc}")
raise