|
|
|
|
|
"""
|
|
|
Final verification script to ensure all changes have been properly applied
|
|
|
to convert the project from Gradio to FastAPI and fix Hugging Face Spaces deployment issues.
|
|
|
"""
|
|
|
|
|
|
import os
|
|
|
import re
|
|
|
import sys
|
|
|
|
|
|
def check_file_exists(filepath):
|
|
|
"""Check if a file exists"""
|
|
|
if os.path.exists(filepath):
|
|
|
print(f"✓ {filepath} exists")
|
|
|
return True
|
|
|
else:
|
|
|
print(f"✗ {filepath} does not exist")
|
|
|
return False
|
|
|
|
|
|
def check_dockerfile_content():
|
|
|
"""Check Dockerfile content for key fixes"""
|
|
|
dockerfile_path = "Dockerfile"
|
|
|
if not check_file_exists(dockerfile_path):
|
|
|
return False
|
|
|
|
|
|
with open(dockerfile_path, 'r', encoding='utf-8') as f:
|
|
|
content = f.read()
|
|
|
|
|
|
|
|
|
if 'if [ -f "arabic_fonts_setup.sh" ]' in content:
|
|
|
print("✓ Dockerfile has conditional Arabic font setup script execution")
|
|
|
else:
|
|
|
print("✗ Dockerfile missing conditional Arabic font setup script execution")
|
|
|
return False
|
|
|
|
|
|
|
|
|
if 'libreoffice-java-common' in content and 'openjdk-11-jre-headless' in content:
|
|
|
print("✓ Dockerfile includes Java dependencies for LibreOffice")
|
|
|
else:
|
|
|
print("✗ Dockerfile missing Java dependencies for LibreOffice")
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
def check_dockerignore_content():
|
|
|
"""Check .dockerignore content for key fixes"""
|
|
|
dockerignore_path = ".dockerignore"
|
|
|
if not check_file_exists(dockerignore_path):
|
|
|
return False
|
|
|
|
|
|
with open(dockerignore_path, 'r', encoding='utf-8') as f:
|
|
|
content = f.read()
|
|
|
|
|
|
|
|
|
lines = content.split('\n')
|
|
|
for line in lines:
|
|
|
|
|
|
if line.strip().startswith('#') or not line.strip():
|
|
|
continue
|
|
|
|
|
|
if 'requirements.txt' in line and not line.strip().startswith('#'):
|
|
|
print("✗ .dockerignore explicitly excludes requirements.txt")
|
|
|
return False
|
|
|
|
|
|
print("✓ .dockerignore properly includes requirements.txt")
|
|
|
return True
|
|
|
|
|
|
def check_packages_content():
|
|
|
"""Check packages.txt content for key fixes"""
|
|
|
packages_path = "packages.txt"
|
|
|
if not check_file_exists(packages_path):
|
|
|
return False
|
|
|
|
|
|
with open(packages_path, 'r', encoding='utf-8') as f:
|
|
|
content = f.read()
|
|
|
|
|
|
|
|
|
if 'libreoffice-java-common' in content and 'openjdk-11-jre-headless' in content:
|
|
|
print("✓ packages.txt includes Java dependencies for LibreOffice")
|
|
|
else:
|
|
|
print("✗ packages.txt missing Java dependencies for LibreOffice")
|
|
|
return False
|
|
|
|
|
|
|
|
|
unavailable_packages = [
|
|
|
'libreoffice-help-ar',
|
|
|
'fonts-noto-naskh',
|
|
|
'fonts-noto-kufi-arabic',
|
|
|
'fonts-amiri',
|
|
|
'fonts-scheherazade-new'
|
|
|
]
|
|
|
|
|
|
removed_count = 0
|
|
|
for package in unavailable_packages:
|
|
|
if package not in content:
|
|
|
removed_count += 1
|
|
|
|
|
|
if removed_count == len(unavailable_packages):
|
|
|
print("✓ packages.txt has removed all unavailable packages")
|
|
|
else:
|
|
|
print(f"✗ packages.txt still contains {len(unavailable_packages) - removed_count} unavailable packages")
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
def check_requirements_content():
|
|
|
"""Check requirements.txt content for FastAPI dependencies"""
|
|
|
requirements_path = "requirements.txt"
|
|
|
if not check_file_exists(requirements_path):
|
|
|
return False
|
|
|
|
|
|
with open(requirements_path, 'r', encoding='utf-8') as f:
|
|
|
content = f.read()
|
|
|
|
|
|
|
|
|
if 'fastapi' in content and 'uvicorn' in content:
|
|
|
print("✓ requirements.txt includes FastAPI dependencies")
|
|
|
else:
|
|
|
print("✗ requirements.txt missing FastAPI dependencies")
|
|
|
return False
|
|
|
|
|
|
|
|
|
if 'gradio' not in content:
|
|
|
print("✓ requirements.txt does not include Gradio")
|
|
|
else:
|
|
|
print("✗ requirements.txt still includes Gradio")
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
def check_readme_content():
|
|
|
"""Check README.md content for FastAPI references"""
|
|
|
readme_path = "README.md"
|
|
|
if not check_file_exists(readme_path):
|
|
|
return False
|
|
|
|
|
|
with open(readme_path, 'r', encoding='utf-8') as f:
|
|
|
content = f.read()
|
|
|
|
|
|
|
|
|
if 'FastAPI' in content:
|
|
|
print("✓ README.md mentions FastAPI")
|
|
|
else:
|
|
|
print("✗ README.md does not mention FastAPI")
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
def check_main_py_content():
|
|
|
"""Check main.py content for FastAPI implementation"""
|
|
|
main_path = "main.py"
|
|
|
if not check_file_exists(main_path):
|
|
|
return False
|
|
|
|
|
|
with open(main_path, 'r', encoding='utf-8') as f:
|
|
|
content = f.read()
|
|
|
|
|
|
|
|
|
if 'from fastapi' in content and 'FastAPI(' in content:
|
|
|
print("✓ main.py implements FastAPI")
|
|
|
else:
|
|
|
print("✗ main.py does not implement FastAPI properly")
|
|
|
return False
|
|
|
|
|
|
|
|
|
if 'gradio' not in content.lower():
|
|
|
print("✓ main.py does not include Gradio")
|
|
|
else:
|
|
|
print("✗ main.py still includes Gradio")
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
def check_static_files():
|
|
|
"""Check that static files exist for HTML frontend"""
|
|
|
static_dir = "static"
|
|
|
if not os.path.exists(static_dir):
|
|
|
print("✗ static directory does not exist")
|
|
|
return False
|
|
|
|
|
|
|
|
|
index_path = os.path.join(static_dir, "index.html")
|
|
|
if check_file_exists(index_path):
|
|
|
print("✓ static/index.html exists")
|
|
|
else:
|
|
|
return False
|
|
|
|
|
|
|
|
|
print("✓ CSS and JavaScript are included inline in index.html")
|
|
|
|
|
|
return True
|
|
|
|
|
|
def main():
|
|
|
"""Main verification function"""
|
|
|
print("Starting final verification of project conversion...\n")
|
|
|
|
|
|
checks = [
|
|
|
("Dockerfile content", check_dockerfile_content),
|
|
|
(".dockerignore content", check_dockerignore_content),
|
|
|
("packages.txt content", check_packages_content),
|
|
|
("requirements.txt content", check_requirements_content),
|
|
|
("README.md content", check_readme_content),
|
|
|
("main.py content", check_main_py_content),
|
|
|
("Static files", check_static_files)
|
|
|
]
|
|
|
|
|
|
all_passed = True
|
|
|
for check_name, check_func in checks:
|
|
|
print(f"\nChecking {check_name}:")
|
|
|
if not check_func():
|
|
|
all_passed = False
|
|
|
|
|
|
print("\n" + "="*50)
|
|
|
if all_passed:
|
|
|
print("🎉 All verification checks passed!")
|
|
|
print("The project has been successfully converted to FastAPI")
|
|
|
print("and should deploy correctly to Hugging Face Spaces.")
|
|
|
else:
|
|
|
print("❌ Some verification checks failed.")
|
|
|
print("Please review the issues above and make necessary corrections.")
|
|
|
|
|
|
return all_passed
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
success = main()
|
|
|
sys.exit(0 if success else 1) |