#!/usr/bin/env python3 """ Git-based deployment to Hugging Face Spaces. This script will guide you through creating and deploying via Git. """ import os import sys import subprocess import getpass import webbrowser from pathlib import Path def run_command(command, description=""): """Run a shell command and return success status.""" print(f"šŸ”„ {description}") try: result = subprocess.run(command, shell=True, check=True, text=True, capture_output=True) if result.stdout: print(f"āœ… {result.stdout.strip()}") return True except subprocess.CalledProcessError as e: print(f"āŒ Error: {e}") if e.stderr: print(f"Error details: {e.stderr.strip()}") return False def check_git(): """Check if git is installed and configured.""" print("šŸ” Checking Git...") if not run_command("git --version", "Checking Git installation"): print("āŒ Git is not installed. Please install Git first.") return False # Check if user is configured name_result = subprocess.run("git config user.name", shell=True, capture_output=True, text=True) email_result = subprocess.run("git config user.email", shell=True, capture_output=True, text=True) if not name_result.stdout.strip(): print("āš ļø Git user name not configured") name = input("Enter your Git user name: ") run_command(f'git config --global user.name "{name}"', "Setting Git user name") if not email_result.stdout.strip(): print("āš ļø Git user email not configured") email = input("Enter your Git user email: ") run_command(f'git config --global user.email "{email}"', "Setting Git user email") return True def get_hf_token(): """Get Hugging Face API token.""" print("\nšŸ” Getting Hugging Face credentials...") # Check if token is set as environment variable hf_token = os.getenv('HF_TOKEN') if hf_token: print("āœ… Found HF_TOKEN environment variable") return hf_token print("Please get your Hugging Face API token:") print("1. Go to: https://huggingface.co/settings/tokens") print("2. Click 'New token'") print("3. Set name: 'spaces-deploy'") print("4. Set role: 'write'") print("5. Copy the token") webbrowser.open("https://huggingface.co/settings/tokens") hf_token = getpass.getpass("Enter your Hugging Face API token: ") return hf_token def create_space(): """Create a new Space on Hugging Face.""" print("\n🌐 Creating Hugging Face Space...") username = input("Enter your Hugging Face username: ") space_name = input("Enter your Space name (e.g., 'memory-chat'): ") # Create Space via API hf_token = get_hf_token() api_url = f"https://huggingface.co/api/spaces/{username}/{space_name}" create_cmd = f'curl -X POST {api_url} -H "Authorization: Bearer {hf_token}" -H "Content-Type: application/json" -d \'{{"private": false, "sdk": "gradio"}}\'' print("Creating Space...") if run_command(create_cmd, "Creating Space on Hugging Face"): print(f"āœ… Space created: https://huggingface.co/spaces/{username}/{space_name}") return username, space_name else: print("āŒ Failed to create Space. Please check your credentials and try again.") return None, None def setup_git_remote(username, space_name, hf_token): """Setup Git remote for the Space.""" print(f"\nšŸ”— Setting up Git remote for {username}/{space_name}...") remote_url = f"https://USER:TOKEN@huggingface.co/spaces/{username}/{space_name}" remote_url = remote_url.replace("USER", username).replace("TOKEN", hf_token) if run_command(f"git remote add origin {remote_url}", "Adding Git remote"): return True else: # Try removing and re-adding run_command("git remote remove origin", "Removing existing remote") return run_command(f"git remote add origin {remote_url}", "Adding Git remote") def deploy_to_spaces(): """Main deployment function.""" print("šŸš€ Memory Chat - Git Deployment to Hugging Face Spaces") print("=" * 60) # Check prerequisites if not check_git(): sys.exit(1) # Check if we're in a git repo if not os.path.exists(".git"): print("šŸ”„ Initializing Git repository...") if not run_command("git init", "Initializing Git repository"): sys.exit(1) # Check if files exist required_files = ['app.py', 'memory_manager.py', 'chat_interface.py', 'config.py', 'requirements.txt', 'README.md'] missing_files = [f for f in required_files if not os.path.exists(f)] if missing_files: print(f"āŒ Missing files: {', '.join(missing_files)}") print("Please ensure all required files are in the current directory.") sys.exit(1) # Create Space or get existing Space details choice = input("\nDo you want to create a new Space? (y/n): ").lower().strip() if choice == 'y': username, space_name = create_space() if not username: sys.exit(1) else: username = input("Enter your Hugging Face username: ") space_name = input("Enter your existing Space name: ") # Setup Git remote hf_token = get_hf_token() if not setup_git_remote(username, space_name, hf_token): print("āŒ Failed to setup Git remote") sys.exit(1) # Add files and commit print("\nšŸ“ Adding files to Git...") if not run_command("git add .", "Adding all files"): sys.exit(1) if not run_command('git commit -m "Initial commit: Memory Chat application"', "Creating commit"): sys.exit(1) # Push to Hugging Face print("\nšŸš€ Pushing to Hugging Face Spaces...") if not run_command("git push -u origin main", "Pushing to remote"): print("āŒ Failed to push to remote. Trying with force...") if not run_command("git push -u origin main --force", "Force pushing to remote"): sys.exit(1) print(f"\nšŸŽ‰ Successfully deployed to: https://huggingface.co/spaces/{username}/{space_name}") print("🌐 Your Space will build automatically. Check the 'Logs' tab for progress.") return username, space_name def main(): """Main entry point.""" if len(sys.argv) > 1 and sys.argv[1] == "--help": print(__doc__) sys.exit(0) try: deploy_to_spaces() except KeyboardInterrupt: print("\nāŒ Deployment cancelled by user") sys.exit(1) except Exception as e: print(f"\nāŒ Deployment failed: {e}") sys.exit(1) if __name__ == "__main__": main()