#!/usr/bin/env python3 """ Safely sync or upload files/folders to Hugging Face Hub (aelgendy/QModel). Automatically excludes sensitive or local folders (.claude, .vscode, .env, .venv, scratch, data). """ import argparse import sys import os # Auto-fallback to Homebrew hf Python if huggingface_hub is not in current environment try: from huggingface_hub import HfApi except ImportError: brew_python = "/opt/homebrew/Cellar/hf/2.2.0/libexec/bin/python" if os.path.exists(brew_python) and sys.executable != brew_python: os.execv(brew_python, [brew_python] + sys.argv) raise DEFAULT_IGNORE = [ ".claude/**", ".vscode/**", ".env*", ".venv/**", "scratch/**", "data/**", "__pycache__/**", "*.pyc", ".DS_Store", ] def main(): parser = argparse.ArgumentParser(description="Upload to Hugging Face with safety exclusions.") parser.add_argument("--repo-id", default="aelgendy/QModel", help="HF Repo ID (default: aelgendy/QModel)") parser.add_argument("--repo-type", default="model", choices=["model", "dataset", "space"], help="Repository type") parser.add_argument("--folder", default=".", help="Local folder to upload (default: current directory)") parser.add_argument("--message", default="Sync repository to Hugging Face", help="Commit message") parser.add_argument("--include-models", action="store_true", help="Include models/ directory in upload") args = parser.parse_args() ignore = list(DEFAULT_IGNORE) if not args.include_models: ignore.append("models/**") ignore.append("*.gguf") print(f"Uploading '{args.folder}' to '{args.repo_id}' (repo_type={args.repo_type})...") print(f"Ignored patterns: {ignore}") api = HfApi() commit = api.upload_folder( repo_id=args.repo_id, folder_path=args.folder, repo_type=args.repo_type, commit_message=args.message, ignore_patterns=ignore, ) print(f"Successfully uploaded! Commit URL: {commit}") if __name__ == "__main__": main()