SmolFactory / scripts /trackio_tonic /deploy_trackio_space.py
Tonic's picture
fix launch script deploy and refactors
93ed7a1 verified
raw
history blame
9.46 kB
#!/usr/bin/env python3
"""
Deployment script for Trackio on Hugging Face Spaces
Automates the process of creating and configuring a Trackio Space
"""
import os
import json
import requests
import subprocess
import sys
from pathlib import Path
from typing import Dict, Any, Optional
class TrackioSpaceDeployer:
"""Deployer for Trackio on Hugging Face Spaces"""
def __init__(self, space_name: str, username: str, token: str):
self.space_name = space_name
self.username = username
self.token = token
self.space_url = f"https://huggingface.co/spaces/{username}/{space_name}"
def create_space(self) -> bool:
"""Create a new Hugging Face Space"""
try:
print(f"Creating Space: {self.space_name}")
# Create space using Hugging Face CLI
cmd = [
"huggingface-cli", "repo", "create",
f"{self.username}/{self.space_name}",
"--type", "space"
]
# Try to create the space first
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
# Try alternative approach without space-specific flags
print("Retrying with basic space creation...")
cmd = [
"huggingface-cli", "repo", "create",
f"{self.username}/{self.space_name}"
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print(f"βœ… Space created successfully: {self.space_url}")
return True
else:
print(f"❌ Failed to create space: {result.stderr}")
return False
except Exception as e:
print(f"❌ Error creating space: {e}")
return False
def upload_files(self) -> bool:
"""Upload necessary files to the Space"""
try:
print("Uploading files to Space...")
# Get the project root directory (3 levels up from this script)
project_root = Path(__file__).parent.parent.parent
templates_dir = project_root / "templates" / "spaces"
# Files to upload from templates/spaces
files_to_upload = [
"app.py",
"requirements.txt"
]
# README.md will be created by configure_space method
# Copy files from templates/spaces to current directory
copied_files = []
for file_name in files_to_upload:
source_path = templates_dir / file_name
if source_path.exists():
import shutil
shutil.copy2(source_path, file_name)
copied_files.append(file_name)
print(f"βœ… Copied {file_name} from templates")
else:
print(f"⚠️ File not found: {source_path}")
# Check if we're in a git repository
try:
subprocess.run(["git", "status"], capture_output=True, check=True)
except subprocess.CalledProcessError:
print("⚠️ Not in a git repository, initializing...")
subprocess.run(["git", "init"], check=True)
subprocess.run(["git", "remote", "add", "origin", f"https://huggingface.co/spaces/{self.username}/{self.space_name}"], check=True)
# Add all files at once
existing_files = [f for f in files_to_upload if os.path.exists(f)]
if existing_files:
subprocess.run(["git", "add"] + existing_files, check=True)
subprocess.run(["git", "add", "README.md"], check=True) # Add README.md that was created in configure_space
subprocess.run(["git", "commit", "-m", "Initial Space setup"], check=True)
# Push to the space
try:
subprocess.run(["git", "push", "origin", "main"], check=True)
print(f"βœ… Uploaded {len(existing_files)} files")
except subprocess.CalledProcessError:
# Try pushing to master branch if main doesn't exist
subprocess.run(["git", "push", "origin", "master"], check=True)
print(f"βœ… Uploaded {len(existing_files)} files")
else:
print("⚠️ No files found to upload")
return True
except Exception as e:
print(f"❌ Error uploading files: {e}")
return False
def configure_space(self) -> bool:
"""Configure the Space settings"""
try:
print("Configuring Space settings...")
# Get the project root directory (3 levels up from this script)
project_root = Path(__file__).parent.parent.parent
templates_dir = project_root / "templates" / "spaces"
readme_template_path = templates_dir / "README.md"
# Read README template if it exists
if readme_template_path.exists():
with open(readme_template_path, 'r', encoding='utf-8') as f:
readme_template = f.read()
# Replace placeholder with actual space URL
readme_content = readme_template.replace("{SPACE_URL}", self.space_url)
# Write README.md for the space
with open("README.md", "w", encoding='utf-8') as f:
f.write(readme_content)
print(f"βœ… Created README.md from template")
else:
print(f"⚠️ README template not found: {readme_template_path}")
# Fallback to basic README
basic_readme = f"""---
title: Trackio Tonic
emoji: 🐠
colorFrom: indigo
colorTo: yellow
sdk: gradio
sdk_version: 5.38.0
app_file: app.py
pinned: true
license: mit
short_description: trackio for training monitoring
---
# Trackio Experiment Tracking
A Gradio interface for experiment tracking and monitoring.
Visit: {self.space_url}
"""
with open("README.md", "w", encoding='utf-8') as f:
f.write(basic_readme)
print(f"βœ… Created basic README.md")
return True
except Exception as e:
print(f"❌ Error configuring space: {e}")
return False
def test_space(self) -> bool:
"""Test if the Space is working correctly"""
try:
print("Testing Space...")
# Wait a bit for the space to build
import time
time.sleep(30)
# Try to access the space
response = requests.get(self.space_url, timeout=10)
if response.status_code == 200:
print(f"βœ… Space is accessible: {self.space_url}")
return True
else:
print(f"⚠️ Space returned status code: {response.status_code}")
return False
except Exception as e:
print(f"❌ Error testing space: {e}")
return False
def deploy(self) -> bool:
"""Complete deployment process"""
print("πŸš€ Starting Trackio Space deployment...")
# Step 1: Create space
if not self.create_space():
return False
# Step 2: Configure space
if not self.configure_space():
return False
# Step 3: Upload files
if not self.upload_files():
return False
# Step 4: Test space
if not self.test_space():
print("⚠️ Space created but may need time to build")
print(f"πŸŽ‰ Deployment completed!")
print(f"πŸ“Š Trackio Space URL: {self.space_url}")
print(f"πŸ”§ Space configuration: {self.space_url}/settings")
return True
def main():
"""Main deployment function"""
print("Trackio Space Deployment Script")
print("=" * 40)
# Get user input
username = input("Enter your Hugging Face username: ").strip()
space_name = input("Enter Space name (e.g., trackio-monitoring): ").strip()
token = input("Enter your Hugging Face token (optional): ").strip()
if not username or not space_name:
print("❌ Username and Space name are required")
sys.exit(1)
# Create deployer
deployer = TrackioSpaceDeployer(space_name, username, token)
# Run deployment
success = deployer.deploy()
if success:
print("\nβœ… Deployment successful!")
print(f"🌐 Your Trackio Space: {deployer.space_url}")
print("\nNext steps:")
print("1. Wait for the Space to build (usually 2-5 minutes)")
print("2. Test the interface by visiting the Space URL")
print("3. Use the Space URL in your training scripts")
else:
print("\n❌ Deployment failed!")
print("Check the error messages above and try again.")
if __name__ == "__main__":
main()