| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| """Contains a helper to get the token from machine (env variable, secret or config file).""" |
|
|
| import configparser |
| import logging |
| import os |
| import warnings |
| from pathlib import Path |
| from threading import Lock |
|
|
| from .. import constants |
| from ._runtime import is_colab_enterprise, is_google_colab |
|
|
|
|
| _IS_GOOGLE_COLAB_CHECKED = False |
| _GOOGLE_COLAB_SECRET_LOCK = Lock() |
| _GOOGLE_COLAB_SECRET: str | None = None |
|
|
| logger = logging.getLogger(__name__) |
|
|
|
|
| def get_token() -> str | None: |
| """ |
| Get token if user is logged in. |
| |
| Note: in most cases, you should use [`huggingface_hub.utils.build_hf_headers`] instead. This method is only useful |
| if you want to retrieve the token for other purposes than sending an HTTP request. |
| |
| Token is retrieved in priority from the `HF_TOKEN` environment variable. Otherwise, we read the token file located |
| in the Hugging Face home folder. Returns None if user is not logged in. To log in, use [`login`] or |
| `hf auth login`. |
| |
| Returns: |
| `str` or `None`: The token, `None` if it doesn't exist. |
| """ |
| return _get_token_from_google_colab() or _get_token_from_environment() or _get_token_from_file() |
|
|
|
|
| def _get_token_from_google_colab() -> str | None: |
| """Get token from Google Colab secrets vault using `google.colab.userdata.get(...)`. |
| |
| Token is read from the vault only once per session and then stored in a global variable to avoid re-requesting |
| access to the vault. |
| """ |
| |
| if not is_google_colab() or is_colab_enterprise(): |
| return None |
|
|
| |
| |
| |
| |
| |
| with _GOOGLE_COLAB_SECRET_LOCK: |
| global _GOOGLE_COLAB_SECRET |
| global _IS_GOOGLE_COLAB_CHECKED |
|
|
| if _IS_GOOGLE_COLAB_CHECKED: |
| return _GOOGLE_COLAB_SECRET |
|
|
| try: |
| from google.colab import userdata |
| from google.colab.errors import Error as ColabError |
| except ImportError: |
| return None |
|
|
| try: |
| token = userdata.get("HF_TOKEN") |
| _GOOGLE_COLAB_SECRET = _clean_token(token) |
| except userdata.NotebookAccessError: |
| |
| |
| warnings.warn( |
| "\nAccess to the secret `HF_TOKEN` has not been granted on this notebook." |
| "\nYou will not be requested again." |
| "\nPlease restart the session if you want to be prompted again." |
| ) |
| _GOOGLE_COLAB_SECRET = None |
| except userdata.SecretNotFoundError: |
| |
| warnings.warn( |
| "\nThe secret `HF_TOKEN` does not exist in your Colab secrets." |
| "\nTo authenticate with the Hugging Face Hub, create a token in your settings tab " |
| "(https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session." |
| "\nYou will be able to reuse this secret in all of your notebooks." |
| "\nPlease note that authentication is recommended but still optional to access public models or datasets." |
| ) |
| _GOOGLE_COLAB_SECRET = None |
| except ColabError as e: |
| |
| warnings.warn( |
| f"\nError while fetching `HF_TOKEN` secret value from your vault: '{str(e)}'." |
| "\nYou are not authenticated with the Hugging Face Hub in this notebook." |
| "\nIf the error persists, please let us know by opening an issue on GitHub " |
| "(https://github.com/huggingface/huggingface_hub/issues/new)." |
| ) |
| _GOOGLE_COLAB_SECRET = None |
|
|
| _IS_GOOGLE_COLAB_CHECKED = True |
| return _GOOGLE_COLAB_SECRET |
|
|
|
|
| def _get_token_from_environment() -> str | None: |
| |
| return _clean_token(os.environ.get("HF_TOKEN") or os.environ.get("HUGGING_FACE_HUB_TOKEN")) |
|
|
|
|
| def _get_token_from_file() -> str | None: |
| try: |
| return _clean_token(Path(constants.HF_TOKEN_PATH).read_text()) |
| except FileNotFoundError: |
| return None |
|
|
|
|
| def get_stored_tokens() -> dict[str, str]: |
| """ |
| Returns the parsed INI file containing the access tokens. |
| The file is located at `HF_STORED_TOKENS_PATH`, defaulting to `~/.cache/huggingface/stored_tokens`. |
| If the file does not exist, an empty dictionary is returned. |
| |
| Returns: `dict[str, str]` |
| Key is the token name and value is the token. |
| """ |
| tokens_path = Path(constants.HF_STORED_TOKENS_PATH) |
| if not tokens_path.exists(): |
| stored_tokens = {} |
| config = configparser.ConfigParser() |
| try: |
| config.read(tokens_path) |
| stored_tokens = {token_name: config.get(token_name, "hf_token") for token_name in config.sections()} |
| except configparser.Error as e: |
| logger.error(f"Error parsing stored tokens file: {e}") |
| stored_tokens = {} |
| return stored_tokens |
|
|
|
|
| def _save_stored_tokens(stored_tokens: dict[str, str]) -> None: |
| """ |
| Saves the given configuration to the stored tokens file. |
| |
| Args: |
| stored_tokens (`dict[str, str]`): |
| The stored tokens to save. Key is the token name and value is the token. |
| """ |
| stored_tokens_path = Path(constants.HF_STORED_TOKENS_PATH) |
|
|
| |
| config = configparser.ConfigParser() |
| for token_name in sorted(stored_tokens.keys()): |
| config.add_section(token_name) |
| config.set(token_name, "hf_token", stored_tokens[token_name]) |
|
|
| stored_tokens_path.parent.mkdir(parents=True, exist_ok=True) |
| with stored_tokens_path.open("w") as config_file: |
| config.write(config_file) |
|
|
|
|
| def _get_token_by_name(token_name: str) -> str | None: |
| """ |
| Get the token by name. |
| |
| Args: |
| token_name (`str`): |
| The name of the token to get. |
| |
| Returns: |
| `str` or `None`: The token, `None` if it doesn't exist. |
| |
| """ |
| stored_tokens = get_stored_tokens() |
| if token_name not in stored_tokens: |
| return None |
| return _clean_token(stored_tokens[token_name]) |
|
|
|
|
| def _save_token(token: str, token_name: str) -> None: |
| """ |
| Save the given token. |
| |
| If the stored tokens file does not exist, it will be created. |
| Args: |
| token (`str`): |
| The token to save. |
| token_name (`str`): |
| The name of the token. |
| """ |
| tokens_path = Path(constants.HF_STORED_TOKENS_PATH) |
| stored_tokens = get_stored_tokens() |
| stored_tokens[token_name] = token |
| _save_stored_tokens(stored_tokens) |
| logger.info(f"The token `{token_name}` has been saved to {tokens_path}") |
|
|
|
|
| def _clean_token(token: str | None) -> str | None: |
| """Clean token by removing trailing and leading spaces and newlines. |
| |
| If token is an empty string, return None. |
| """ |
| if token is None: |
| return None |
| return token.replace("\r", "").replace("\n", "").strip() or None |
|
|