Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions 62 tests/test_notebook_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import importlib.util
from pathlib import Path


MODULE_PATH = Path(__file__).parents[1] / "unsloth" / "notebook_token.py"


def _load_module():
spec = importlib.util.spec_from_file_location("notebook_token_under_test", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module


def test_detects_colab_hf_token(monkeypatch):
module = _load_module()
monkeypatch.delenv("HF_TOKEN", raising = False)
monkeypatch.setenv("COLAB_RELEASE_TAG", "release")
monkeypatch.delenv("KAGGLE_KERNEL_RUN_TYPE", raising = False)
monkeypatch.delenv("KAGGLE_URL_BASE", raising = False)
monkeypatch.setattr(module, "_read_colab_secret", lambda name: f" {name}-value ")

assert module.detect_notebook_hf_token() == "HF_TOKEN-value"
assert module.os.environ["HF_TOKEN"] == "HF_TOKEN-value"


def test_detects_kaggle_hf_token_after_missing_colab_secret(monkeypatch):
module = _load_module()
monkeypatch.delenv("HF_TOKEN", raising = False)
monkeypatch.setenv("COLAB_BACKEND_VERSION", "version")
monkeypatch.setenv("KAGGLE_KERNEL_RUN_TYPE", "Interactive")
monkeypatch.setattr(module, "_read_colab_secret", lambda _name: None)
monkeypatch.setattr(module, "_read_kaggle_secret", lambda name: f"{name}-kaggle")

assert module.detect_notebook_hf_token() == "HF_TOKEN-kaggle"


def test_explicit_hf_token_is_not_overridden(monkeypatch):
module = _load_module()
monkeypatch.setenv("HF_TOKEN", "explicit")
monkeypatch.setenv("COLAB_RELEASE_TAG", "release")
monkeypatch.setattr(
module,
"_read_colab_secret",
lambda _name: (_ for _ in ()).throw(AssertionError("secret store was accessed")),
)

assert module.detect_notebook_hf_token() == "explicit"


def test_secret_access_failure_is_non_fatal(monkeypatch):
module = _load_module()
monkeypatch.delenv("HF_TOKEN", raising = False)
monkeypatch.setenv("KAGGLE_URL_BASE", "https://www.kaggle.com")
monkeypatch.setattr(
module,
"_read_kaggle_secret",
lambda _name: (_ for _ in ()).throw(RuntimeError("not granted")),
)

assert module.detect_notebook_hf_token() is None
assert "HF_TOKEN" not in module.os.environ
8 changes: 8 additions & 0 deletions 8 unsloth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@

os.environ["UNSLOTH_IS_PRESENT"] = "1"

# Hosted notebooks keep secrets outside the process environment. Resolve the
# conventional HF_TOKEN secret before Hugging Face libraries freeze their auth
# configuration during import.
from .notebook_token import detect_notebook_hf_token as _detect_notebook_hf_token

_detect_notebook_hf_token()
del _detect_notebook_hf_token

# Relax Metal's context-store timeout before MLX modules can initialize Metal.
# Keep an explicit user value authoritative.
if platform.system() == "Darwin" and platform.machine() == "arm64":
Expand Down
54 changes: 54 additions & 0 deletions 54 unsloth/notebook_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2023-present Daniel Han-Chen & the Unsloth team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.

"""Load the Hugging Face token exposed by hosted notebook secret stores."""

import importlib
import importlib.util
import os


HF_TOKEN_SECRET_NAME = "HF_TOKEN"


def _read_colab_secret(name):
if importlib.util.find_spec("google.colab") is None:
return None
userdata = importlib.import_module("google.colab.userdata")
return userdata.get(name)


def _read_kaggle_secret(name):
if importlib.util.find_spec("kaggle_secrets") is None:
return None
kaggle_secrets = importlib.import_module("kaggle_secrets")
return kaggle_secrets.UserSecretsClient().get_secret(name)


def detect_notebook_hf_token(secret_name = HF_TOKEN_SECRET_NAME):
"""Populate ``HF_TOKEN`` from Colab or Kaggle, without overriding user config.

Access failures are deliberately silent: missing/ungranted notebook secrets
are normal, and Hugging Face can still use anonymous access or its token cache.
"""
existing = os.environ.get("HF_TOKEN")
if existing:
return existing

readers = []
if os.environ.get("COLAB_RELEASE_TAG") or os.environ.get("COLAB_BACKEND_VERSION"):
readers.append(_read_colab_secret)
if os.environ.get("KAGGLE_KERNEL_RUN_TYPE") or os.environ.get("KAGGLE_URL_BASE"):
readers.append(_read_kaggle_secret)

for reader in readers:
try:
token = reader(secret_name)
except Exception:
continue
if isinstance(token, str) and token.strip():
os.environ["HF_TOKEN"] = token.strip()
return os.environ["HF_TOKEN"]
return None
Morty Proxy This is a proxified and sanitized view of the page, visit original site.