|
|
|
|
|
""" |
|
|
HuggingFace Spaces Pre-Deployment Validation Script |
|
|
Validates the LifeUnity AI Cognitive Twin System before deployment |
|
|
""" |
|
|
|
|
|
import os |
|
|
import sys |
|
|
from pathlib import Path |
|
|
|
|
|
print("="*60) |
|
|
print("HuggingFace Spaces Pre-Deployment Validation") |
|
|
print("LifeUnity AI β Cognitive Twin System") |
|
|
print("="*60) |
|
|
print() |
|
|
|
|
|
|
|
|
print("β
STEP 1: VERIFY PROJECT STRUCTURE") |
|
|
print("-" * 60) |
|
|
|
|
|
required_dirs = [ |
|
|
"app", |
|
|
"app/utils", |
|
|
"data", |
|
|
"logs" |
|
|
] |
|
|
|
|
|
required_files = [ |
|
|
"app/main.py", |
|
|
"app/mood_detection.py", |
|
|
"app/memory_graph.py", |
|
|
"app/insights_engine.py", |
|
|
"app/user_profile.py", |
|
|
"app/utils/preprocess.py", |
|
|
"app/utils/embedder.py", |
|
|
"app/utils/logger.py", |
|
|
"requirements.txt", |
|
|
"HF_README.md" |
|
|
] |
|
|
|
|
|
all_dirs_ok = True |
|
|
for dir_path in required_dirs: |
|
|
if Path(dir_path).exists(): |
|
|
print(f" β {dir_path}/") |
|
|
else: |
|
|
print(f" β {dir_path}/ - MISSING") |
|
|
all_dirs_ok = False |
|
|
|
|
|
print() |
|
|
|
|
|
all_files_ok = True |
|
|
for file_path in required_files: |
|
|
if Path(file_path).exists(): |
|
|
size = Path(file_path).stat().st_size |
|
|
print(f" β {file_path} ({size} bytes)") |
|
|
else: |
|
|
print(f" β {file_path} - MISSING") |
|
|
all_files_ok = False |
|
|
|
|
|
print() |
|
|
|
|
|
if all_dirs_ok and all_files_ok: |
|
|
print("β
Structure validation PASSED") |
|
|
else: |
|
|
print("β Structure validation FAILED") |
|
|
sys.exit(1) |
|
|
|
|
|
print() |
|
|
|
|
|
|
|
|
print("β
STEP 2: VALIDATE STREAMLIT APP ENTRYPOINT") |
|
|
print("-" * 60) |
|
|
|
|
|
if Path("app/main.py").exists(): |
|
|
with open("app/main.py", "r") as f: |
|
|
content = f.read() |
|
|
if "import streamlit" in content or "from streamlit" in content: |
|
|
print(" β app/main.py contains Streamlit imports") |
|
|
else: |
|
|
print(" β app/main.py missing Streamlit imports") |
|
|
sys.exit(1) |
|
|
|
|
|
if "st.set_page_config" in content: |
|
|
print(" β app/main.py has page configuration") |
|
|
else: |
|
|
print(" β app/main.py missing page configuration") |
|
|
|
|
|
print(" β Entrypoint: app/main.py (as specified in HF_README.md)") |
|
|
else: |
|
|
print(" β app/main.py NOT FOUND") |
|
|
sys.exit(1) |
|
|
|
|
|
print() |
|
|
print("β
Entrypoint validation PASSED") |
|
|
print() |
|
|
|
|
|
|
|
|
print("β
STEP 3: VERIFY DEPENDENCIES") |
|
|
print("-" * 60) |
|
|
|
|
|
required_packages = [ |
|
|
"streamlit", |
|
|
"torch", |
|
|
"transformers", |
|
|
"sentence-transformers", |
|
|
"opencv-python-headless", |
|
|
"numpy", |
|
|
"pandas", |
|
|
"pillow", |
|
|
"scikit-learn", |
|
|
"networkx", |
|
|
"fer", |
|
|
"tensorflow", |
|
|
"plotly", |
|
|
"matplotlib" |
|
|
] |
|
|
|
|
|
if Path("requirements.txt").exists(): |
|
|
with open("requirements.txt", "r") as f: |
|
|
requirements_content = f.read().lower() |
|
|
|
|
|
missing_packages = [] |
|
|
for package in required_packages: |
|
|
if package.lower().replace("-", "_") in requirements_content.replace("-", "_"): |
|
|
print(f" β {package}") |
|
|
else: |
|
|
print(f" β {package} - MISSING") |
|
|
missing_packages.append(package) |
|
|
|
|
|
if missing_packages: |
|
|
print() |
|
|
print(f"β Missing packages: {', '.join(missing_packages)}") |
|
|
sys.exit(1) |
|
|
else: |
|
|
print() |
|
|
print("β
Dependencies validation PASSED") |
|
|
else: |
|
|
print(" β requirements.txt NOT FOUND") |
|
|
sys.exit(1) |
|
|
|
|
|
print() |
|
|
|
|
|
|
|
|
print("β
STEP 4: CONFIGURE HUGGINGFACE SPACE") |
|
|
print("-" * 60) |
|
|
|
|
|
if Path("HF_README.md").exists(): |
|
|
with open("HF_README.md", "r") as f: |
|
|
hf_content = f.read() |
|
|
|
|
|
if "sdk: streamlit" in hf_content: |
|
|
print(" β SDK set to Streamlit") |
|
|
else: |
|
|
print(" β SDK not set to Streamlit") |
|
|
sys.exit(1) |
|
|
|
|
|
if "app_file: app/main.py" in hf_content: |
|
|
print(" β app_file points to app/main.py") |
|
|
else: |
|
|
print(" β app_file not explicitly set (will default to app.py)") |
|
|
|
|
|
if "gradio" not in hf_content.lower(): |
|
|
print(" β No Gradio configuration found") |
|
|
else: |
|
|
print(" β Gradio references found in config") |
|
|
|
|
|
print() |
|
|
print("β
HuggingFace Space configuration PASSED") |
|
|
else: |
|
|
print(" β HF_README.md NOT FOUND") |
|
|
sys.exit(1) |
|
|
|
|
|
print() |
|
|
|
|
|
|
|
|
print("β
STEP 5: RUN BUILD HEALTH CHECK") |
|
|
print("-" * 60) |
|
|
|
|
|
|
|
|
import py_compile |
|
|
syntax_errors = [] |
|
|
|
|
|
for file_path in required_files: |
|
|
if file_path.endswith(".py"): |
|
|
try: |
|
|
py_compile.compile(file_path, doraise=True) |
|
|
print(f" β {file_path} - syntax OK") |
|
|
except py_compile.PyCompileError as e: |
|
|
print(f" β {file_path} - syntax ERROR") |
|
|
syntax_errors.append(file_path) |
|
|
|
|
|
print() |
|
|
|
|
|
if syntax_errors: |
|
|
print(f"β Syntax errors in: {', '.join(syntax_errors)}") |
|
|
sys.exit(1) |
|
|
|
|
|
|
|
|
print(" Checking for webcam/camera code...") |
|
|
webcam_issues = [] |
|
|
webcam_check_files = [f for f in required_files if f.endswith("main.py") or f.endswith("mood_detection.py")] |
|
|
for file_path in webcam_check_files: |
|
|
if Path(file_path).exists(): |
|
|
with open(file_path, "r") as f: |
|
|
content = f.read() |
|
|
if "camera_input" in content: |
|
|
webcam_issues.append(f"{file_path} contains camera_input") |
|
|
if "VideoCapture" in content: |
|
|
webcam_issues.append(f"{file_path} contains VideoCapture") |
|
|
|
|
|
if webcam_issues: |
|
|
print() |
|
|
for issue in webcam_issues: |
|
|
print(f" β {issue}") |
|
|
print("β Webcam code found (not compatible with HF Spaces)") |
|
|
sys.exit(1) |
|
|
else: |
|
|
print(" β No webcam code found (HF Spaces compatible)") |
|
|
|
|
|
print() |
|
|
|
|
|
|
|
|
print(" Checking relative imports...") |
|
|
import_issues = [] |
|
|
for file_path in required_files: |
|
|
if file_path.endswith(".py") and file_path != "app/main.py": |
|
|
with open(file_path, "r") as f: |
|
|
content = f.read() |
|
|
|
|
|
if "from app." in content: |
|
|
print(f" β {file_path} uses relative imports") |
|
|
elif "import" in content and file_path.startswith("app/"): |
|
|
|
|
|
if "from app.utils" in content: |
|
|
print(f" β {file_path} uses relative imports") |
|
|
else: |
|
|
import_issues.append(file_path) |
|
|
|
|
|
if import_issues: |
|
|
print() |
|
|
print(f" β Check imports in: {', '.join(import_issues)}") |
|
|
|
|
|
print() |
|
|
|
|
|
|
|
|
if Path("data").exists(): |
|
|
print(" β data/ directory exists (for JSON storage)") |
|
|
else: |
|
|
print(" β data/ directory will be created at runtime") |
|
|
|
|
|
print() |
|
|
print("β
Build health check PASSED") |
|
|
print() |
|
|
|
|
|
|
|
|
print("="*60) |
|
|
print("β
DEPLOYMENT READINESS REPORT") |
|
|
print("="*60) |
|
|
print() |
|
|
print("Project: LifeUnity AI β Cognitive Twin System") |
|
|
print("Status: β
READY FOR HUGGINGFACE SPACES DEPLOYMENT") |
|
|
print() |
|
|
print("Configuration:") |
|
|
print(" β’ SDK: Streamlit") |
|
|
print(" β’ Entry Point: app/main.py") |
|
|
print(" β’ Hardware: CPU Basic (free tier)") |
|
|
print(" β’ Visibility: Public") |
|
|
print() |
|
|
print("Pages Available:") |
|
|
print(" 1. β
Dashboard - Metrics & trends") |
|
|
print(" 2. β
Emotion Detection - Image upload only") |
|
|
print(" 3. β
Cognitive Memory - Notes with embeddings") |
|
|
print(" 4. β
AI Insights - Wellness reports") |
|
|
print() |
|
|
print("Features:") |
|
|
print(" β’ β
No webcam code (HF Spaces compatible)") |
|
|
print(" β’ β
Image upload for emotion detection") |
|
|
print(" β’ β
Sentence-BERT embeddings (all-MiniLM-L6-v2)") |
|
|
print(" β’ β
Local rule-based AI insights (no API keys)") |
|
|
print(" β’ β
JSON storage in /data directory") |
|
|
print(" β’ β
All dependencies cloud-safe") |
|
|
print() |
|
|
print("Next Steps:") |
|
|
print(" 1. Create Space on HuggingFace") |
|
|
print(" 2. Select Streamlit SDK") |
|
|
print(" 3. Upload project files") |
|
|
print(" 4. Rename HF_README.md to README.md") |
|
|
print(" 5. Space will auto-deploy in 5-10 minutes") |
|
|
print() |
|
|
print("="*60) |
|
|
print("β
ALL VALIDATION CHECKS PASSED") |
|
|
print("="*60) |
|
|
|