avoigt1121 Claude Opus 4.8 commited on
Commit
ce5168d
·
1 Parent(s): 5cb2737

fix(loader): authenticate huggingface.co downloads via HF_TOKEN

Browse files

_resolve_to_local_path fetched URLs with plain urllib (no auth), so private HF
dataset h5ads returned HTTP 401 on the Space. For /resolve/ URLs with a token,
use hf_hub_download (handles the LFS redirect + HF_TOKEN auth); fall back to
urllib for public/non-HF hosts. Requires an HF_TOKEN Space secret with read
access to the private data repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files changed (1) hide show
  1. src/tools/bulk_dataset_tools.py +30 -0
src/tools/bulk_dataset_tools.py CHANGED
@@ -79,9 +79,39 @@ def _resolve_to_local_path(path_or_url: str) -> tuple[str, bool]:
79
  caller is responsible for its own existence check.
80
  """
81
  if path_or_url.startswith(("http://", "https://", "ftp://")):
 
82
  import tempfile
83
  import urllib.request
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  suffix = Path(path_or_url.split("?", 1)[0]).suffix or ".h5ad"
86
  with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
87
  with urllib.request.urlopen(path_or_url) as resp:
 
79
  caller is responsible for its own existence check.
80
  """
81
  if path_or_url.startswith(("http://", "https://", "ftp://")):
82
+ import os
83
  import tempfile
84
  import urllib.request
85
 
86
+ # Private huggingface.co repos need an authenticated request. Use
87
+ # hf_hub_download for resolve URLs when a token is present — it handles
88
+ # the LFS redirect and HF_TOKEN auth correctly. Fall back to plain
89
+ # urllib otherwise (public files, non-HF hosts).
90
+ if "huggingface.co/" in path_or_url and "/resolve/" in path_or_url:
91
+ _hf_token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")
92
+ if _hf_token:
93
+ try:
94
+ from huggingface_hub import hf_hub_download
95
+
96
+ _after = path_or_url.split("huggingface.co/", 1)[1]
97
+ _repo_type = "model"
98
+ if _after.startswith("datasets/"):
99
+ _repo_type, _after = "dataset", _after[len("datasets/"):]
100
+ elif _after.startswith("spaces/"):
101
+ _repo_type, _after = "space", _after[len("spaces/"):]
102
+ _repo_id, _file = _after.split("/resolve/", 1)
103
+ _revision, _filename = _file.split("/", 1)
104
+ local = hf_hub_download(
105
+ repo_id=_repo_id,
106
+ filename=_filename,
107
+ repo_type=_repo_type,
108
+ revision=_revision,
109
+ token=_hf_token,
110
+ )
111
+ return local, False # HF cache file — caller must not delete it
112
+ except Exception:
113
+ pass # fall through to unauthenticated urllib (e.g. public file)
114
+
115
  suffix = Path(path_or_url.split("?", 1)[0]).suffix or ".h5ad"
116
  with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
117
  with urllib.request.urlopen(path_or_url) as resp: