dotnet-forge-ultra / forge-cli.py
krisshattanicole's picture
Upload forge-cli.py with huggingface_hub
03f5d60 verified
Raw
History Blame Contribute Delete
9.71 kB
#!/usr/bin/env python
"""
.NET Forge Ultra - CLI Management Tool
Complete command-line interface for managing your reverse engineering workstation
"""
import argparse
import os
import sys
import subprocess
import json
from pathlib import Path
from datetime import datetime
# Colors for terminal
class Colors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def print_header(text):
print(f"\n{Colors.HEADER}{Colors.BOLD}{'='*60}{Colors.ENDC}")
print(f"{Colors.HEADER}{Colors.BOLD} {text}{Colors.ENDC}")
print(f"{Colors.HEADER}{Colors.BOLD}{'='*60}{Colors.ENDC}\n")
def print_success(text):
print(f"[OK] {text}")
def print_error(text):
print(f"[ERROR] {text}")
def print_warning(text):
print(f"[WARN] {text}")
def print_info(text):
print(f"[INFO] {text}")
def run_command(cmd, cwd=None, check=True):
"""Run shell command and return result"""
try:
result = subprocess.run(
cmd,
shell=True,
cwd=cwd,
capture_output=True,
text=True,
check=check
)
return result.returncode == 0, result.stdout, result.stderr
except subprocess.CalledProcessError as e:
return False, e.stdout or "", e.stderr or ""
def check_hf_login():
"""Check if logged in to HuggingFace"""
try:
from huggingface_hub import HfApi
api = HfApi()
user = api.whoami()
return True, user["name"]
except:
return False, None
def hf_login():
"""Login to HuggingFace via CLI"""
print_header("HuggingFace Login")
print_info("Starting authentication...")
print_info("If browser doesn't open, go to: https://huggingface.co/settings/tokens")
print_info("Create a token and paste it below:\n")
try:
from huggingface_hub import login, interpreter_login
interpreter_login()
print_success("Logged in to HuggingFace")
return True
except Exception as e:
print_error(f"Login failed: {e}")
return False
def create_space(name, sdk="gradio", hardware="cpu-basic"):
"""Create HuggingFace Space"""
print_info(f"Creating space: {name} (SDK: {sdk}, Hardware: {hardware})")
try:
from huggingface_hub import create_repo
create_repo(
repo_id=name,
repo_type="space",
space_sdk=sdk,
space_hardware=hardware,
exist_ok=True
)
print_success(f"Space created: {name}")
return True
except Exception as e:
print_error(f"Failed to create space: {e}")
return False
def deploy_to_space(space_name, files, sdk="gradio"):
"""Deploy files to HuggingFace Space"""
print_info(f"Deploying to {space_name}...")
try:
from huggingface_hub import upload_file
for file in files:
if os.path.exists(file):
print_info(f"Uploading {file}...")
upload_file(
path_or_fileobj=file,
path_in_repo=os.path.basename(file),
repo_id=space_name,
repo_type="space",
)
print_success(f"Uploaded {file}")
else:
print_warning(f"File not found: {file}")
return True
except Exception as e:
print_error(f"Deployment failed: {e}")
return False
def set_space_secret(space_name, key, value):
"""Set space secret via API"""
print_info(f"Setting secret {key} for {space_name}")
# Note: Secrets must be set via web UI or API with proper auth
print_warning("Secrets must be set via HuggingFace web UI:")
print_info(f" https://huggingface.co/spaces/{space_name}/settings")
return True
def check_space_status(space_name):
"""Check space deployment status"""
print_info(f"Checking status of {space_name}...")
try:
from huggingface_hub import HfApi
api = HfApi()
space = api.space_info(space_name)
print_success(f"Space exists: {space.id}")
print_info(f"SDK: {space.sdk}")
print_info(f"Last modified: {space.lastModified}")
return True
except Exception as e:
print_error(f"Space not found: {e}")
return False
def list_spaces():
"""List all user spaces"""
print_header("Your HuggingFace Spaces")
try:
from huggingface_hub import HfApi
api = HfApi()
user = api.whoami()
spaces = api.list_spaces(author=user["name"])
for space in spaces:
print(f"\n {Colors.OKCYAN}{space.id}{Colors.ENDC}")
print(f" SDK: {space.sdk}")
print(f" URL: https://huggingface.co/spaces/{space.id}")
return True
except Exception as e:
print_error(f"Failed to list spaces: {e}")
return False
def install_requirements(req_file):
"""Install Python requirements"""
print_info(f"Installing requirements from {req_file}...")
success, stdout, stderr = run_command(f"pip install -r {req_file}")
if success:
print_success("Requirements installed")
return True
else:
print_error(f"Failed: {stderr}")
return False
def build_react_app(cwd):
"""Build React app"""
print_info("Building React app...")
success, stdout, stderr = run_command("npm run build", cwd=cwd)
if success:
print_success("Build complete")
return True
else:
print_error(f"Build failed: {stderr}")
return False
def show_space_url(space_name):
"""Display space URL"""
url = f"https://huggingface.co/spaces/{space_name}"
print_header("Space URL")
print(f"\n {Colors.OKGREEN}{Colors.BOLD}{url}{Colors.ENDC}\n")
def revoke_token_warning():
"""Show token revocation warning"""
print_header("SECURITY WARNING")
print(f"{Colors.FAIL}{Colors.BOLD}If you exposed a HuggingFace token:{Colors.ENDC}\n")
print("1. Revoke it immediately:")
print(f" {Colors.OKBLUE}https://huggingface.co/settings/tokens{Colors.ENDC}\n")
print("2. Create a new token with Read permissions only")
print("3. Add it to your Space secrets\n")
def main():
parser = argparse.ArgumentParser(
description=".NET Forge Ultra - CLI Management Tool",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
%(prog)s login # Login to HuggingFace
%(prog)s list # List your spaces
%(prog)s deploy dotnet-forge-ultra
%(prog)s status dotnet-forge-ultra
%(prog)s install # Install requirements
%(prog)s build # Build React app
%(prog)s url dotnet-forge-ultra
"""
)
subparsers = parser.add_subparsers(dest="command", help="Commands")
# Login command
subparsers.add_parser("login", help="Login to HuggingFace")
# List command
subparsers.add_parser("list", help="List all spaces")
# Deploy command
deploy_parser = subparsers.add_parser("deploy", help="Deploy to space")
deploy_parser.add_argument("space", help="Space name")
deploy_parser.add_argument("--files", nargs="+", help="Files to upload")
deploy_parser.add_argument("--sdk", default="gradio", help="Space SDK")
# Status command
status_parser = subparsers.add_parser("status", help="Check space status")
status_parser.add_argument("space", help="Space name")
# URL command
url_parser = subparsers.add_parser("url", help="Show space URL")
url_parser.add_argument("space", help="Space name")
# Install command
install_parser = subparsers.add_parser("install", help="Install requirements")
install_parser.add_argument("--file", default="requirements.txt", help="Requirements file")
# Build command
build_parser = subparsers.add_parser("build", help="Build React app")
build_parser.add_argument("--dir", help="App directory")
# Security command
subparsers.add_parser("security", help="Show security warnings")
# Init command
init_parser = subparsers.add_parser("init", help="Initialize new space")
init_parser.add_argument("name", help="Space name")
init_parser.add_argument("--sdk", default="gradio", help="Space SDK")
init_parser.add_argument("--hardware", default="cpu-basic", help="Hardware tier")
args = parser.parse_args()
if args.command == "login":
hf_login()
elif args.command == "list":
list_spaces()
elif args.command == "deploy":
if not check_hf_login()[0]:
print_error("Not logged in. Run: forge login")
sys.exit(1)
files = args.files or ["app.py", "requirements.txt", "README.md"]
deploy_to_space(args.space, files, args.sdk)
elif args.command == "status":
check_space_status(args.space)
elif args.command == "url":
show_space_url(args.space)
elif args.command == "install":
install_requirements(args.file)
elif args.command == "build":
build_react_app(args.dir or os.getcwd())
elif args.command == "security":
revoke_token_warning()
elif args.command == "init":
if not check_hf_login()[0]:
print_error("Not logged in. Run: forge login")
sys.exit(1)
create_space(args.name, args.sdk, args.hardware)
else:
parser.print_help()
if __name__ == "__main__":
main()