Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Pre-deployment validation script | |
| Checks that the project is ready for HF deployment | |
| """ | |
| import os | |
| import sys | |
| from pathlib import Path | |
| def check_file_exists(filename, description): | |
| """Check if a file exists and return status""" | |
| if os.path.exists(filename): | |
| size = os.path.getsize(filename) | |
| print(f"โ {filename} ({size:,} bytes) - {description}") | |
| return True | |
| else: | |
| print(f"โ Missing: {filename} - {description}") | |
| return False | |
| def check_file_content(filename, required_content): | |
| """Check if file contains required content""" | |
| try: | |
| with open(filename, 'r', encoding='utf-8') as f: | |
| content = f.read() | |
| missing = [] | |
| for item in required_content: | |
| if item not in content: | |
| missing.append(item) | |
| if missing: | |
| print(f"โ ๏ธ {filename} missing: {', '.join(missing)}") | |
| return False | |
| else: | |
| print(f"โ {filename} content validated") | |
| return True | |
| except Exception as e: | |
| print(f"โ Error reading {filename}: {e}") | |
| return False | |
| def validate_project(): | |
| """Run all validation checks""" | |
| print("Pre-Deployment Validation") | |
| print("=" * 40) | |
| all_good = True | |
| # Required files | |
| print("\n๐ File Structure Check:") | |
| required_files = [ | |
| ("docs/README.md", "HF Space configuration and docs"), | |
| ("src/app.py", "Main Gradio application"), | |
| ("src/mlx_campp.py", "MLX model implementation"), | |
| ("src/conversion_utils.py", "Conversion utilities"), | |
| ("requirements.txt", "Dependencies"), | |
| ("tests/test_converter.py", "Test suite"), | |
| (".gitignore", "Git ignore patterns"), | |
| ("docs/DEPLOYMENT_GUIDE.md", "Deployment instructions") | |
| ] | |
| for filename, desc in required_files: | |
| if not check_file_exists(filename, desc): | |
| all_good = False | |
| # Check README.md has HF Space configuration | |
| print("\n๐๏ธ HF Space Configuration Check:") | |
| readme_required = [ | |
| "title: CAM++ MLX Converter", | |
| "emoji: ๐ค", | |
| "sdk: gradio", | |
| "app_file: app.py" | |
| ] | |
| if not check_file_content("docs/README.md", readme_required): | |
| all_good = False | |
| # Check app.py has required components | |
| print("\nโ๏ธ App.py Component Check:") | |
| app_required = [ | |
| "import gradio as gr", | |
| "from mlx_campp import CAMPPModel", | |
| "from conversion_utils import ConversionUtils", | |
| "def convert_model", | |
| "interface.launch()" | |
| ] | |
| if not check_file_content("src/app.py", app_required): | |
| all_good = False | |
| # Check requirements.txt has essential packages | |
| print("\n๐ฆ Dependencies Check:") | |
| req_required = [ | |
| "mlx>=0.19.0", | |
| "gradio>=4.44.0", | |
| "huggingface_hub", | |
| "torch", | |
| "numpy" | |
| ] | |
| if not check_file_content("requirements.txt", req_required): | |
| all_good = False | |
| # Check for common issues | |
| print("\nCommon Issues Check:") | |
| # Check if any Python files have import errors | |
| try: | |
| # Try importing without actually running MLX (which might not be installed) | |
| import ast | |
| for py_file in ["src/app.py", "src/mlx_campp.py", "src/conversion_utils.py"]: | |
| try: | |
| with open(py_file, 'r') as f: | |
| ast.parse(f.read()) | |
| print(f"โ {py_file} syntax is valid") | |
| except SyntaxError as e: | |
| print(f"โ Syntax error in {py_file}: {e}") | |
| all_good = False | |
| except Exception as e: | |
| print(f"โ ๏ธ Could not validate Python syntax: {e}") | |
| # File size checks | |
| print("\n๐ File Size Check:") | |
| for filename in ["src/app.py", "src/mlx_campp.py", "src/conversion_utils.py"]: | |
| if os.path.exists(filename): | |
| size = os.path.getsize(filename) | |
| if size < 1000: # Less than 1KB is suspicious | |
| print(f"โ ๏ธ {filename} seems too small ({size} bytes)") | |
| elif size > 100000: # More than 100KB is unusual for these files | |
| print(f"โ ๏ธ {filename} seems very large ({size} bytes)") | |
| else: | |
| print(f"โ {filename} size looks good ({size:,} bytes)") | |
| # Check for secrets/tokens in files | |
| print("\n๐ Security Check:") | |
| security_ok = True | |
| sensitive_patterns = ["hf_", "token", "password", "secret", "key"] | |
| for py_file in ["src/app.py", "src/mlx_campp.py", "src/conversion_utils.py"]: | |
| try: | |
| with open(py_file, 'r') as f: | |
| content = f.read().lower() | |
| for pattern in sensitive_patterns: | |
| if pattern in content and "example" not in content: | |
| # Check if it's actually a hardcoded secret | |
| lines = content.split('\n') | |
| for i, line in enumerate(lines): | |
| if pattern in line and '=' in line and len(line.split('=')[1].strip().strip('"\'')) > 10: | |
| print(f"โ ๏ธ Possible hardcoded secret in {py_file}:{i+1}") | |
| security_ok = False | |
| break | |
| except Exception: | |
| pass | |
| if security_ok: | |
| print("โ No hardcoded secrets detected") | |
| # Final assessment | |
| print("\n" + "=" * 40) | |
| if all_good: | |
| print("๐ PROJECT IS READY FOR DEPLOYMENT!") | |
| print("\nNext steps:") | |
| print("1. Run: chmod +x deploy.sh && ./deploy.sh") | |
| print("2. Or follow DEPLOYMENT_GUIDE.md for manual deployment") | |
| print("3. Monitor your HF Space after deployment") | |
| return True | |
| else: | |
| print("โ PROJECT NEEDS FIXES BEFORE DEPLOYMENT") | |
| print("\nPlease fix the issues above before deploying.") | |
| return False | |
| def show_deployment_preview(): | |
| """Show what the deployed space will look like""" | |
| print("\n๐ Deployment Preview:") | |
| print("Your HF Space will have:") | |
| print("โข URL: https://your-username-campp-mlx-converter.hf.space") | |
| print("โข Title: ๐ค CAM++ MLX Converter") | |
| print("โข Interface: Clean Gradio form for model conversion") | |
| print("โข Features: PyTorchโMLX conversion with quantization") | |
| print("โข Output: Models uploaded to mlx-community automatically") | |
| if __name__ == "__main__": | |
| print("CAM++ MLX Converter - Pre-Deployment Validation") | |
| print("=" * 50) | |
| is_valid = validate_project() | |
| if is_valid: | |
| show_deployment_preview() | |
| sys.exit(0) | |
| else: | |
| sys.exit(1) | |