| | |
| | """ |
| | Check if the app is ready for deployment to Hugging Face Spaces |
| | """ |
| |
|
| | import os |
| | import sys |
| | from pathlib import Path |
| | import logging |
| |
|
| | |
| | logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') |
| | logger = logging.getLogger(__name__) |
| |
|
| | def check_required_files(): |
| | """Check if all required files exist""" |
| | required_files = [ |
| | 'app.py', |
| | 'requirements.txt', |
| | 'Dockerfile', |
| | '.dockerignore', |
| | 'README.md', |
| | 'download_models.py', |
| | 'templates/index.html', |
| | 'static/css/style.css', |
| | 'static/js/script.js' |
| | ] |
| | |
| | missing_files = [] |
| | for file_path in required_files: |
| | if not Path(file_path).exists(): |
| | missing_files.append(file_path) |
| | else: |
| | logger.info(f"β
{file_path}") |
| | |
| | if missing_files: |
| | logger.error(f"β Missing files: {missing_files}") |
| | return False |
| | |
| | logger.info("β
All required files present") |
| | return True |
| |
|
| | def check_directory_structure(): |
| | """Check directory structure""" |
| | required_dirs = [ |
| | 'models', |
| | 'utils', |
| | 'static', |
| | 'static/css', |
| | 'static/js', |
| | 'static/uploads', |
| | 'templates' |
| | ] |
| | |
| | missing_dirs = [] |
| | for dir_path in required_dirs: |
| | if not Path(dir_path).exists(): |
| | missing_dirs.append(dir_path) |
| | else: |
| | logger.info(f"β
{dir_path}/") |
| | |
| | if missing_dirs: |
| | logger.error(f"β Missing directories: {missing_dirs}") |
| | return False |
| | |
| | logger.info("β
Directory structure correct") |
| | return True |
| |
|
| | def check_imports(): |
| | """Check if main imports work""" |
| | try: |
| | logger.info("π Testing imports...") |
| | |
| | |
| | from flask import Flask |
| | logger.info("β
Flask import OK") |
| | |
| | |
| | import utils.suppress_warnings |
| | logger.info("β
Utils import OK") |
| | |
| | |
| | try: |
| | from models.model_loader import ModelLoader |
| | logger.info("β
Models import OK") |
| | except Exception as e: |
| | logger.info(f"β οΈ Models import skipped (models will be downloaded on deployment): {e}") |
| | |
| | logger.info("β
Critical imports successful") |
| | return True |
| | |
| | except ImportError as e: |
| | logger.error(f"β Import error: {e}") |
| | return False |
| |
|
| | def check_docker_setup(): |
| | """Check Docker-related files""" |
| | docker_files = ['Dockerfile', '.dockerignore'] |
| | |
| | for file_path in docker_files: |
| | if not Path(file_path).exists(): |
| | logger.error(f"β Missing {file_path}") |
| | return False |
| | |
| | |
| | if Path(file_path).stat().st_size == 0: |
| | logger.error(f"β {file_path} is empty") |
| | return False |
| | |
| | logger.info(f"β
{file_path} exists and not empty") |
| | |
| | return True |
| |
|
| | def check_readme(): |
| | """Check README has Hugging Face metadata""" |
| | readme_path = Path('README.md') |
| | if not readme_path.exists(): |
| | logger.error("β README.md missing") |
| | return False |
| | |
| | content = readme_path.read_text(encoding='utf-8') |
| | |
| | |
| | if not content.startswith('---'): |
| | logger.error("β README.md missing Hugging Face metadata header") |
| | return False |
| | |
| | required_fields = ['title:', 'emoji:', 'sdk:', 'app_port:'] |
| | for field in required_fields: |
| | if field not in content: |
| | logger.error(f"β README.md missing field: {field}") |
| | return False |
| | |
| | logger.info("β
README.md has proper Hugging Face metadata") |
| | return True |
| |
|
| | def main(): |
| | """Main deployment check""" |
| | logger.info("π Checking deployment readiness for Hugging Face Spaces...") |
| | logger.info("=" * 60) |
| | |
| | checks = [ |
| | ("Required Files", check_required_files), |
| | ("Directory Structure", check_directory_structure), |
| | ("Docker Setup", check_docker_setup), |
| | ("README Metadata", check_readme), |
| | ("Python Imports", check_imports), |
| | ] |
| | |
| | passed = 0 |
| | failed = 0 |
| | |
| | for check_name, check_func in checks: |
| | logger.info(f"\nπ {check_name}...") |
| | if check_func(): |
| | passed += 1 |
| | logger.info(f"β
{check_name} PASSED") |
| | else: |
| | failed += 1 |
| | logger.error(f"β {check_name} FAILED") |
| | |
| | logger.info("\n" + "=" * 60) |
| | logger.info(f"π Results: {passed} passed, {failed} failed") |
| | |
| | if failed == 0: |
| | logger.info("π Deployment ready! You can upload to Hugging Face Spaces.") |
| | logger.info("π‘ Don't forget to:") |
| | logger.info(" 1. Upload model weights to Hugging Face Model Hub") |
| | logger.info(" 2. Update URLs in download_models.py") |
| | logger.info(" 3. Test the space after deployment") |
| | return 0 |
| | else: |
| | logger.error("β Please fix the issues above before deploying") |
| | return 1 |
| |
|
| | if __name__ == "__main__": |
| | sys.exit(main()) |