Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| HOLOKIA-AVATAR - Point d'entrée pour Hugging Face Spaces | |
| Avatar 3D interactif avec IA conversationnelle | |
| """ | |
| import os | |
| import sys | |
| import subprocess | |
| import time | |
| import logging | |
| from pathlib import Path | |
| # Configuration du logging | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s - %(levelname)s - %(message)s" | |
| ) | |
| logger = logging.getLogger("HOLOKIA-AVATAR") | |
| def check_requirements(): | |
| """Vérifie que toutes les dépendances sont installées.""" | |
| try: | |
| import fastapi | |
| import uvicorn | |
| import gtts | |
| import faster_whisper | |
| import langchain_groq | |
| logger.info("✅ Toutes les dépendances sont installées") | |
| return True | |
| except ImportError as e: | |
| logger.error(f"❌ Dépendance manquante: {e}") | |
| return False | |
| def check_environment(): | |
| """Vérifie les variables d'environnement requises.""" | |
| groq_key = os.getenv("GROQ_API_KEY") | |
| if not groq_key: | |
| logger.warning("⚠️ GROQ_API_KEY n'est pas définie") | |
| logger.info("💡 Ajoutez votre clé API Groq dans les secrets du Space") | |
| # Ne pas arrêter l'application, juste avertir | |
| return True | |
| logger.info("✅ Variables d'environnement configurées") | |
| return True | |
| def check_frontend(): | |
| """Vérifie que le frontend est disponible.""" | |
| nginx_html = Path("/usr/share/nginx/html") | |
| if nginx_html.exists() and any(nginx_html.iterdir()): | |
| logger.info("✅ Frontend disponible (construit dans le Dockerfile)") | |
| return True | |
| else: | |
| logger.error("❌ Frontend non disponible") | |
| return False | |
| def test_services(): | |
| """Teste que tous les services backend sont accessibles.""" | |
| logger.info("🔍 Test des services backend...") | |
| import requests | |
| services = [ | |
| ("TTS", "http://localhost:5000/health"), | |
| ("STT", "http://localhost:5001/health"), | |
| ("LLM", "http://localhost:5002/health"), | |
| ("Live Stream", "http://localhost:5003/health"), | |
| ] | |
| all_ok = True | |
| for name, url in services: | |
| try: | |
| response = requests.get(url, timeout=5) | |
| if response.status_code == 200: | |
| logger.info(f"✅ {name}: OK") | |
| else: | |
| logger.error(f"❌ {name}: Erreur (status {response.status_code})") | |
| all_ok = False | |
| except Exception as e: | |
| logger.error(f"❌ {name}: Erreur de connexion - {e}") | |
| all_ok = False | |
| return all_ok | |
| def start_services(): | |
| """Démarre tous les services backend.""" | |
| logger.info("🚀 Démarrage des services backend...") | |
| try: | |
| # Vérifier que le script existe | |
| start_script = Path("start_services.py") | |
| if not start_script.exists(): | |
| logger.error(f"❌ Script de démarrage non trouvé: {start_script}") | |
| return False | |
| # Démarrer les services en arrière-plan | |
| logger.info("⏳ Démarrage des services en arrière-plan...") | |
| process = subprocess.Popen([ | |
| sys.executable, str(start_script) | |
| ], cwd=os.getcwd(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
| # Attendre un peu pour que les services démarrent | |
| time.sleep(15) | |
| # Vérifier que le processus est toujours en vie | |
| if process.poll() is not None: | |
| logger.error("❌ Les services backend se sont arrêtés prématurément") | |
| stdout, stderr = process.communicate() | |
| logger.error(f"STDOUT: {stdout.decode()}") | |
| logger.error(f"STDERR: {stderr.decode()}") | |
| return False | |
| # Tester que les services sont accessibles | |
| if not test_services(): | |
| logger.error("❌ Certains services ne sont pas accessibles") | |
| return False | |
| # Test détaillé des services | |
| logger.info("🔍 Test détaillé des services...") | |
| try: | |
| result = subprocess.run([sys.executable, "debug_websocket.py"], | |
| capture_output=True, text=True, timeout=30) | |
| if result.stdout: | |
| logger.info(f"Résultats des tests WebSocket:\n{result.stdout}") | |
| if result.stderr: | |
| logger.error(f"Erreurs des tests WebSocket:\n{result.stderr}") | |
| except Exception as e: | |
| logger.warning(f"Impossible d'exécuter les tests WebSocket: {e}") | |
| # Test détaillé des services | |
| logger.info("🔍 Test détaillé des services...") | |
| try: | |
| result = subprocess.run([sys.executable, "test_services_detailed.py"], | |
| capture_output=True, text=True, timeout=120) | |
| if result.stdout: | |
| logger.info(f"Résultats des tests détaillés:\n{result.stdout}") | |
| if result.stderr: | |
| logger.error(f"Erreurs des tests détaillés:\n{result.stderr}") | |
| except Exception as e: | |
| logger.warning(f"Impossible d'exécuter les tests détaillés: {e}") | |
| logger.info("✅ Services backend démarrés et testés") | |
| return True | |
| except Exception as e: | |
| logger.error(f"❌ Erreur lors du démarrage des services: {e}") | |
| return False | |
| def start_nginx(): | |
| """Démarre Nginx.""" | |
| logger.info("🌐 Démarrage de Nginx...") | |
| try: | |
| # Vérifier la configuration Nginx | |
| result = subprocess.run(["nginx", "-t"], capture_output=True, text=True) | |
| if result.returncode != 0: | |
| logger.error(f"❌ Configuration Nginx invalide: {result.stderr}") | |
| return False | |
| logger.info("✅ Configuration Nginx valide") | |
| # Démarrer Nginx en mode daemon | |
| subprocess.run(["nginx"], check=True) | |
| logger.info("✅ Nginx démarré") | |
| return True | |
| except subprocess.CalledProcessError as e: | |
| logger.error(f"❌ Erreur Nginx: {e}") | |
| return False | |
| except Exception as e: | |
| logger.error(f"❌ Erreur inattendue avec Nginx: {e}") | |
| return False | |
| def main(): | |
| """Point d'entrée principal.""" | |
| logger.info("🤖 HOLOKIA-AVATAR - Démarrage sur Hugging Face Spaces (v2.2)") | |
| logger.info(f"📁 Répertoire de travail: {os.getcwd()}") | |
| logger.info(f"🐍 Version Python: {sys.version}") | |
| try: | |
| # Vérifications préliminaires | |
| if not check_requirements(): | |
| logger.error("❌ Vérification des dépendances échouée") | |
| sys.exit(1) | |
| if not check_environment(): | |
| logger.warning("⚠️ Vérification de l'environnement échouée, mais on continue") | |
| if not check_frontend(): | |
| logger.error("❌ Vérification du frontend échouée") | |
| sys.exit(1) | |
| # Démarrage des services | |
| if not start_services(): | |
| logger.error("❌ Impossible de démarrer les services backend") | |
| # Ne pas arrêter, essayer de continuer avec Nginx seulement | |
| # Démarrage de Nginx | |
| if not start_nginx(): | |
| logger.error("❌ Impossible de démarrer Nginx") | |
| sys.exit(1) | |
| logger.info("🎉 Application démarrée avec succès!") | |
| logger.info("🌐 Serveur web accessible sur le port 7860") | |
| # Garder l'application en vie | |
| try: | |
| while True: | |
| time.sleep(60) | |
| logger.info("💓 Application en vie...") | |
| except KeyboardInterrupt: | |
| logger.info("🛑 Arrêt de l'application") | |
| except Exception as e: | |
| logger.error(f"❌ Erreur critique: {e}") | |
| sys.exit(1) | |
| if __name__ == "__main__": | |
| main() |