Pak-Angels-AI-Tutor / deploy_to_huggingface.py
Khanmx99's picture
Deploy Pak Angels AI Tutor
cebd780 verified
Raw
History Blame Contribute Delete
6.14 kB
"""Upload Pak Angels AI Tutor to a Hugging Face Space.
Required environment variables:
HF_TOKEN: A Hugging Face access token with write access to the Space.
HF_SPACE_ID: The Space repo id, for example "your-username/pak-angels-ai-tutor".
Optional environment variables:
HF_COMMIT_MESSAGE: Custom commit message for the upload.
HF_PRIVATE_SPACE: Set to "true" to create a private Space when using --create.
"""
from __future__ import annotations
import argparse
import os
import sys
from pathlib import Path
from huggingface_hub import HfApi
from huggingface_hub.utils import HfHubHTTPError
PROJECT_ROOT = Path(__file__).resolve().parent
DEFAULT_IGNORE_PATTERNS = [
".env",
".env.local",
".env.*.local",
".git/",
".git/**",
".venv/",
".venv/**",
"venv/",
"venv/**",
"__pycache__/",
"__pycache__/**",
"*.pyc",
".DS_Store",
".pytest_cache/",
".pytest_cache/**",
".ruff_cache/",
".ruff_cache/**",
".mypy_cache/",
".mypy_cache/**",
"dist/",
"dist/**",
"build/",
"build/**",
"*.egg-info/",
"*.egg-info/**",
"*.log",
"tmp/",
"tmp/**",
"temp/",
"temp/**",
]
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Upload the current Pak Angels AI Tutor project to Hugging Face Spaces."
)
parser.add_argument(
"--space-id",
default=os.getenv("HF_SPACE_ID", "").strip(),
help='Hugging Face Space id, for example "username/pak-angels-ai-tutor".',
)
parser.add_argument(
"--token",
default=os.getenv("HF_TOKEN", "").strip(),
help="Hugging Face write token. Prefer setting HF_TOKEN instead of passing this flag.",
)
parser.add_argument(
"--commit-message",
default=os.getenv("HF_COMMIT_MESSAGE", "Deploy Pak Angels AI Tutor"),
help="Commit message shown in the Hugging Face Space repository.",
)
parser.add_argument(
"--repo-type",
default="space",
choices=["space"],
help="Repository type. Spaces deployments use 'space'.",
)
parser.add_argument(
"--create",
action="store_true",
help="Create the Gradio Space if it does not already exist.",
)
parser.add_argument(
"--private",
action="store_true",
default=os.getenv("HF_PRIVATE_SPACE", "").lower() in {"1", "true", "yes"},
help="Create the Space as private when --create is used.",
)
return parser.parse_args()
def validate_inputs(space_id: str, token: str) -> None:
missing = []
if not space_id:
missing.append("HF_SPACE_ID")
if not token:
missing.append("HF_TOKEN")
if missing:
joined = ", ".join(missing)
raise ValueError(
f"Missing required setting(s): {joined}. Set them as environment variables "
"or pass --space-id and --token."
)
if "/" not in space_id:
raise ValueError('HF_SPACE_ID should look like "username/space-name".')
placeholder_values = {
"your_hugging_face_write_token_here",
"your-token",
"your_token",
}
placeholder_space_ids = {
"your-username/your-space-name",
"username/space-name",
"your-username/pak-angels-ai-tutor",
}
if token in placeholder_values:
raise ValueError("HF_TOKEN is still a placeholder. Use a real Hugging Face write token.")
if space_id in placeholder_space_ids:
raise ValueError(
"HF_SPACE_ID is still a placeholder. Use your real Space id, such as "
'"mohammadanwarkhan/pak-angels-ai-tutor".'
)
def ensure_space_exists(api: HfApi, args: argparse.Namespace) -> None:
if not args.create:
return
api.create_repo(
repo_id=args.space_id,
repo_type=args.repo_type,
private=args.private,
space_sdk="gradio",
exist_ok=True,
)
def preflight_check(api: HfApi, args: argparse.Namespace) -> None:
whoami = api.whoami()
account_name = whoami.get("name") or whoami.get("fullname") or "authenticated account"
print(f"Authenticated with Hugging Face as: {account_name}")
try:
api.repo_info(repo_id=args.space_id, repo_type=args.repo_type)
print(f"Space is accessible: {args.space_id}")
except HfHubHTTPError as error:
if args.create:
raise
raise RuntimeError(
f"The token cannot access the Space '{args.space_id}'. Check that the Space id "
"is exact and that this Hugging Face token has write access to that Space. "
"If the Space does not exist, rerun with --create."
) from error
def upload_project(args: argparse.Namespace) -> str:
api = HfApi(token=args.token)
ensure_space_exists(api, args)
preflight_check(api, args)
api.upload_folder(
folder_path=str(PROJECT_ROOT),
repo_id=args.space_id,
repo_type=args.repo_type,
commit_message=args.commit_message,
ignore_patterns=DEFAULT_IGNORE_PATTERNS,
)
return f"https://huggingface.co/spaces/{args.space_id}"
def main() -> int:
args = parse_args()
try:
validate_inputs(args.space_id, args.token)
url = upload_project(args)
except ValueError as error:
print(f"Configuration error: {error}", file=sys.stderr)
return 2
except HfHubHTTPError as error:
print(f"Hugging Face upload failed: {error}", file=sys.stderr)
print(
"Check that HF_SPACE_ID is your real Space id, HF_TOKEN is a real write token, "
"and the Space exists. If it does not exist, rerun with --create.",
file=sys.stderr,
)
return 1
except Exception as error:
print(f"Deployment failed: {error}", file=sys.stderr)
return 1
print("Deployment upload complete.")
print(f"Space URL: {url}")
print("Remember to set OPENAI_API_KEY in the Space secrets before testing the tutor.")
return 0
if __name__ == "__main__":
raise SystemExit(main())