my-gradio-momask / pre_deploy_check.py
nocapdev's picture
Upload folder using huggingface_hub
4df9599 verified
"""
Pre-deployment validation script for Hugging Face Spaces
Checks all dependencies and files before deployment
"""
import os
import sys
import subprocess
from pathlib import Path
import importlib.util
# Fix Windows encoding issues
if sys.platform == 'win32':
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
class Colors:
GREEN = '\033[92m'
RED = '\033[91m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
RESET = '\033[0m'
def print_success(msg):
print(f"{Colors.GREEN}{Colors.RESET} {msg}")
def print_error(msg):
print(f"{Colors.RED}{Colors.RESET} {msg}")
def print_warning(msg):
print(f"{Colors.YELLOW}{Colors.RESET} {msg}")
def print_info(msg):
print(f"{Colors.BLUE}{Colors.RESET} {msg}")
def check_python_version():
"""Check Python version"""
print("\n[1/8] Checking Python version...")
version = sys.version_info
if version.major == 3 and version.minor >= 8:
print_success(f"Python {version.major}.{version.minor}.{version.micro}")
return True
else:
print_error(f"Python {version.major}.{version.minor}.{version.micro} - Requires Python 3.8+")
return False
def check_required_files():
"""Check for required files"""
print("\n[2/8] Checking required files...")
required_files = {
'app.py': 'Main application file',
'requirements.txt': 'Dependencies list',
'README.md': 'Space documentation'
}
all_found = True
for file, description in required_files.items():
if Path(file).exists():
print_success(f"{file:<20} - {description}")
else:
print_error(f"{file:<20} - MISSING ({description})")
all_found = False
return all_found
def check_dependencies():
"""Check if all dependencies can be imported"""
print("\n[3/8] Checking critical dependencies...")
critical_deps = {
'torch': 'PyTorch',
'gradio': 'Gradio',
'numpy': 'NumPy',
'einops': 'Einops',
'scipy': 'SciPy',
'matplotlib': 'Matplotlib',
'trimesh': 'Trimesh',
'sklearn': 'Scikit-learn',
'clip': 'OpenAI CLIP',
}
all_installed = True
for module, name in critical_deps.items():
try:
__import__(module)
print_success(f"{name:<20}")
except ImportError:
print_error(f"{name:<20} - NOT INSTALLED")
all_installed = False
return all_installed
def check_requirements_txt():
"""Validate requirements.txt format"""
print("\n[4/8] Validating requirements.txt...")
if not Path('requirements.txt').exists():
print_error("requirements.txt not found")
return False
with open('requirements.txt', 'r', encoding='utf-8') as f:
content = f.read()
issues = []
# Check for encoding issues
if '��' in content or '→' in content:
issues.append("File has encoding issues (contains weird characters)")
# Check for missing versions (but allow some packages without versions like ftfy, regex)
lines = content.split('\n')
missing_versions = []
allowed_without_version = ['ftfy', 'regex', 'wheel', 'setuptools', 'pip'] # Dependencies that don't need strict versions
for line in lines:
line = line.strip()
if line and not line.startswith('#'):
if '==' not in line and '>=' not in line and not line.startswith('git+'):
# Check if it's in the allowed list
if not any(allowed in line.lower() for allowed in allowed_without_version):
missing_versions.append(line)
if missing_versions:
issues.append(f"Packages without version: {', '.join(missing_versions[:5])}")
# Check for commented critical packages (only check actual package lines, not section headers)
lines_lower = [line.strip().lower() for line in lines if line.strip() and not line.strip().startswith('#')]
has_gradio = any('gradio' in line for line in lines_lower)
if not has_gradio:
# Check if it's commented out in package lines
commented_lines = [line.strip().lower() for line in lines if line.strip().startswith('#')]
if any(line.startswith('# gradio==') or line.startswith('# gradio>=') or line.startswith('#gradio') for line in commented_lines):
issues.append("gradio is commented out")
if issues:
for issue in issues:
print_error(issue)
return False
else:
print_success("requirements.txt is valid")
return True
def check_model_paths():
"""Check if model checkpoint paths exist"""
print("\n[5/8] Checking model checkpoints...")
checkpoints_dir = './checkpoints'
if not Path(checkpoints_dir).exists():
print_error(f"Checkpoints directory not found: {checkpoints_dir}")
return False
dataset_name = 't2m'
required_paths = [
f'{checkpoints_dir}/{dataset_name}/t2m_nlayer8_nhead6_ld384_ff1024_cdp0.1_rvq6ns',
f'{checkpoints_dir}/{dataset_name}/rvq_nq6_dc512_nc512_noshare_qdp0.2',
f'{checkpoints_dir}/{dataset_name}/length_estimator',
]
all_found = True
for path in required_paths:
if Path(path).exists():
print_success(f"Found: {Path(path).name}")
else:
print_warning(f"Missing: {path}")
all_found = False
if not all_found:
print_warning("Some checkpoints are missing - you'll need to download them")
return True # Don't fail on missing checkpoints as they might be downloaded later
def check_readme():
"""Check README.md content"""
print("\n[6/8] Checking README.md...")
if not Path('README.md').exists():
print_warning("README.md not found")
return False
with open('README.md', 'r', encoding='utf-8') as f:
content = f.read()
required_sections = ['title:', 'sdk:', 'sdk_version:']
missing = [s for s in required_sections if s.lower() not in content.lower()]
if missing:
print_warning(f"README.md missing metadata: {', '.join(missing)}")
print_info("Add YAML frontmatter for Hugging Face Spaces")
return False
else:
print_success("README.md has required metadata")
return True
def check_huggingface_token():
"""Check if Hugging Face token is set"""
print("\n[7/8] Checking Hugging Face token...")
token = os.getenv('HUGGINGFACE_TOKEN')
if token:
print_success("HUGGINGFACE_TOKEN environment variable is set")
return True
else:
print_error("HUGGINGFACE_TOKEN not set")
print_info("Set with: $env:HUGGINGFACE_TOKEN = 'hf_your_token'")
return False
def check_app_syntax():
"""Check if app.py has valid Python syntax"""
print("\n[8/8] Checking app.py syntax...")
try:
with open('app.py', 'r', encoding='utf-8') as f:
compile(f.read(), 'app.py', 'exec')
print_success("app.py has valid syntax")
return True
except SyntaxError as e:
print_error(f"Syntax error in app.py: {e}")
return False
def main():
print("=" * 70)
print(" " * 18 + "Pre-Deployment Validation")
print("=" * 70)
checks = [
("Python Version", check_python_version),
("Required Files", check_required_files),
("Dependencies", check_dependencies),
("Requirements.txt", check_requirements_txt),
("Model Paths", check_model_paths),
("README.md", check_readme),
("HF Token", check_huggingface_token),
("App Syntax", check_app_syntax),
]
results = {}
for name, check_func in checks:
try:
results[name] = check_func()
except Exception as e:
print_error(f"Check failed with error: {e}")
results[name] = False
# Summary
print("\n" + "=" * 70)
print(" " * 25 + "SUMMARY")
print("=" * 70)
passed = sum(1 for v in results.values() if v)
total = len(results)
for name, result in results.items():
status = f"{Colors.GREEN}PASS{Colors.RESET}" if result else f"{Colors.RED}FAIL{Colors.RESET}"
print(f"{name:<30} {status}")
print("=" * 70)
print(f"\nPassed: {passed}/{total}")
if passed == total:
print_success("\n✓ All checks passed! Ready to deploy.")
print_info("\nRun: python deploy.py")
return 0
else:
print_error("\n✗ Some checks failed. Fix issues before deploying.")
print_info("\nFix the issues above and run this script again.")
return 1
if __name__ == "__main__":
sys.exit(main())