""" HuggingFace Hub. Unlike the other schemes, we don't implement a `SchemeClient` subclass here because `huggingface_hub` handles the caching logic internally in essentially the same way. """ from pathlib import Path from typing import Optional import huggingface_hub as hf_hub import requests from huggingface_hub.utils import ( EntryNotFoundError, RepositoryNotFoundError, RevisionNotFoundError, ) from ..common import PathOrStr from ..version import VERSION def hf_hub_download( model_identifier: str, filename: Optional[str], cache_dir: Optional[PathOrStr] = None ) -> Path: revision: Optional[str] if "@" in model_identifier: repo_id = model_identifier.split("@")[0] revision = model_identifier.split("@")[1] else: repo_id = model_identifier revision = None if filename is not None: return Path( hf_hub.hf_hub_download( repo_id=repo_id, filename=filename, revision=revision, library_name="cached_path", library_version=VERSION, cache_dir=cache_dir, ) ) else: return Path(hf_hub.snapshot_download(repo_id, revision=revision, cache_dir=cache_dir)) def hf_get_from_cache(url: str, cache_dir: Optional[PathOrStr] = None) -> Path: if cache_dir is not None: cache_dir = Path(cache_dir).expanduser() cache_dir.mkdir(parents=True, exist_ok=True) # Remove the 'hf://' prefix identifier = url[5:] if identifier.count("/") > 1: filename = "/".join(identifier.split("/")[2:]) model_identifier = "/".join(identifier.split("/")[:2]) return hf_hub_download(model_identifier, filename, cache_dir) elif identifier.count("/") == 1: # 'hf://' URLs like 'hf://xxxx/yyyy' are potentially ambiguous, # because this could refer to either: # 1. the file 'yyyy' in the 'xxxx' repository, or # 2. the repo 'yyyy' under the user/org name 'xxxx'. # We default to (1), but if we get a 404 error or 401 error then we try (2) try: model_identifier, filename = identifier.split("/") return hf_hub_download(model_identifier, filename, cache_dir) except (RepositoryNotFoundError, RevisionNotFoundError, EntryNotFoundError): return hf_hub_download(identifier, None, cache_dir) except requests.exceptions.HTTPError as exc: if exc.response is not None and exc.response.status_code in {401, 404}: return hf_hub_download(identifier, None, cache_dir) else: raise except ValueError: return hf_hub_download(identifier, None, cache_dir) else: return hf_hub_download(identifier, None, cache_dir)