PureOne's picture
Release CHISA-RSI v1.0.0
7d43d30 verified
Raw History Blame Contribute Delete
8.24 kB
#!/usr/bin/env python3
"""Robust one-click uploader for the CHISA-RSI Hugging Face release.
Works with:
* HF_TOKEN environment variable, or
* an existing `hf auth login`, or
* interactive Hugging Face login when run from a terminal.
HF_REPO_ID is optional. If omitted, the script derives the authenticated
username and proposes the release's default repository name.
"""
from __future__ import annotations
import argparse
import os
import sys
from pathlib import Path
DEFAULT_SLUG = "CHISA-RSI-Proof-Carrying-Continuous-Capability-Closure-v1.0.0"
REQUIRED_FILES = (
"README.md",
"CHISA_RSI_v1.0.0.pdf",
"CLAIMS_AND_SCOPE.md",
"THEOREMS.json",
"AI_AGENT_INDEX.json",
"CITATION.cff",
)
def die(message: str, code: int = 1) -> "NoReturn":
print(f"\nERROR: {message}", file=sys.stderr)
raise SystemExit(code)
def package_check(folder: Path) -> None:
missing = [name for name in REQUIRED_FILES if not (folder / name).is_file()]
if missing:
die("Release package is incomplete. Missing: " + ", ".join(missing), 2)
print(f"Package check: OK ({len(REQUIRED_FILES)} required files found)")
def load_hf():
try:
import huggingface_hub
from huggingface_hub import HfApi, get_token, login
except Exception as exc:
die(
"huggingface_hub is not installed or failed to import. "
"Run: python -m pip install -U huggingface_hub\n"
f"Details: {exc}"
)
return huggingface_hub, HfApi, get_token, login
def obtain_token(api, get_token, login) -> str:
# HF_TOKEN has priority. Otherwise use the cached token from `hf auth login`.
token = os.environ.get("HF_TOKEN") or get_token()
if token:
try:
who = api.whoami(token=token)
except Exception as exc:
die(
"A Hugging Face token was found, but authentication failed. "
"Use a current personal User Access Token with WRITE permission.\n"
f"Details: {exc}",
3,
)
name = who.get("name") or who.get("fullname") or "authenticated user"
print(f"Authentication: OK ({name})")
return token
if not sys.stdin.isatty():
die(
"No Hugging Face authentication was found. Set HF_TOKEN to a WRITE token "
"or run `hf auth login` first.",
3,
)
print("\nNo HF_TOKEN or cached login was found.")
print("Starting Hugging Face login. Your token is not written into this release folder.")
try:
try:
login(skip_if_logged_in=False)
except TypeError:
# Compatibility with older huggingface_hub releases.
login()
except Exception as exc:
die(
"Interactive Hugging Face login failed. You can instead run `hf auth login` "
"in a terminal and then launch this uploader again.\n"
f"Details: {exc}",
3,
)
token = get_token()
if not token:
die("Login finished without producing an accessible Hugging Face token.", 3)
try:
who = api.whoami(token=token)
except Exception as exc:
die(f"Authentication verification failed after login: {exc}", 3)
name = who.get("name") or who.get("fullname") or "authenticated user"
print(f"Authentication: OK ({name})")
return token
def choose_repo_id(api, token: str, cli_repo_id: str | None) -> str:
repo_id = cli_repo_id or os.environ.get("HF_REPO_ID")
if repo_id:
return repo_id.strip()
who = api.whoami(token=token)
username = who.get("name")
if not username:
die("Could not determine your Hugging Face username from the authenticated account.", 3)
default = f"{username}/{DEFAULT_SLUG}"
if sys.stdin.isatty():
print(f"\nDefault repository: {default}")
entered = input("Repository ID [press Enter to accept]: ").strip()
repo_id = entered or default
else:
repo_id = default
if "/" not in repo_id or repo_id.startswith("/") or repo_id.endswith("/"):
die("HF_REPO_ID must look like `username-or-org/repository-name`.", 2)
return repo_id
def repo_url(repo_id: str, repo_type: str) -> str:
if repo_type == "dataset":
return f"https://huggingface.co/datasets/{repo_id}"
if repo_type == "space":
return f"https://huggingface.co/spaces/{repo_id}"
return f"https://huggingface.co/{repo_id}"
def main() -> int:
parser = argparse.ArgumentParser(description="Upload CHISA-RSI v1.0.0 to Hugging Face.")
parser.add_argument("--repo-id", help="Override HF_REPO_ID (username-or-org/repo-name).")
parser.add_argument(
"--repo-type",
choices=("model", "dataset", "space"),
default=os.environ.get("HF_REPO_TYPE", "model"),
help="Hugging Face repository type (default: model).",
)
parser.add_argument(
"--check-only",
action="store_true",
help="Validate the local package and Python dependency without contacting Hugging Face.",
)
args = parser.parse_args()
folder = Path(__file__).resolve().parent
os.chdir(folder)
package_check(folder)
hub, HfApi, get_token, login = load_hf()
print(f"huggingface_hub: {hub.__version__}")
if args.check_only:
print("Uploader self-test: OK")
return 0
api = HfApi()
token = obtain_token(api, get_token, login)
repo_id = choose_repo_id(api, token, args.repo_id)
repo_type = args.repo_type
print("\nUpload target")
print(f" repo: {repo_id}")
print(f" type: {repo_type}")
print(" visibility: public")
try:
# Current Hub clients support `visibility`; older ones use `private`.
try:
api.create_repo(
repo_id=repo_id,
repo_type=repo_type,
visibility="public",
exist_ok=True,
token=token,
)
except TypeError:
api.create_repo(
repo_id=repo_id,
repo_type=repo_type,
private=False,
exist_ok=True,
token=token,
)
except Exception as exc:
die(
"Could not create/open the target repository. Check that the token has WRITE "
"permission and that you own the namespace (or have write access to the organization).\n"
f"Details: {exc}",
4,
)
try:
result = api.upload_folder(
repo_id=repo_id,
repo_type=repo_type,
folder_path=str(folder),
path_in_repo="",
commit_message="Release CHISA-RSI v1.0.0",
token=token,
ignore_patterns=[
"*.zip",
"__pycache__/**",
"*.pyc",
".git/**",
"hf_upload.log",
],
)
if result is not None:
print(f"Upload commit: {getattr(result, 'commit_url', result)}")
except Exception as exc:
die(
"Upload failed. Re-running is safe: Hugging Face upload_folder is resumable and "
"skips content already committed.\n"
f"Details: {exc}",
5,
)
# Verify that the core public-release files actually reached the repository.
try:
remote = set(api.list_repo_files(repo_id=repo_id, repo_type=repo_type, token=token))
missing_remote = [name for name in REQUIRED_FILES if name not in remote]
if missing_remote:
die(
"Hugging Face accepted the upload, but verification found missing files: "
+ ", ".join(missing_remote),
6,
)
except SystemExit:
raise
except Exception as exc:
die(f"Upload finished but remote verification failed: {exc}", 6)
url = repo_url(repo_id, repo_type)
print("\nSUCCESS: upload and remote verification both passed.")
print(url)
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except KeyboardInterrupt:
print("\nCancelled by user.")
raise SystemExit(130)