- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
308 lines
10 KiB
Python
308 lines
10 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Script de Lancement de Démonstration Réelle
|
|
Auteur : Dom, Alice, Kiro - 7 janvier 2026
|
|
|
|
Lance tous les services nécessaires pour une démonstration réelle du Visual Workflow Builder.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import subprocess
|
|
import threading
|
|
import signal
|
|
from pathlib import Path
|
|
|
|
class RealDemoLauncher:
|
|
"""
|
|
Gestionnaire de lancement pour la démonstration réelle
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.processes = []
|
|
self.base_path = Path(__file__).parent
|
|
self.is_running = True
|
|
|
|
def check_dependencies(self):
|
|
"""
|
|
Vérifie que toutes les dépendances sont installées
|
|
"""
|
|
print("🔍 Vérification des dépendances...")
|
|
|
|
# Vérifier Python
|
|
if sys.version_info < (3, 8):
|
|
print("❌ Python 3.8+ requis")
|
|
return False
|
|
print("✅ Python OK")
|
|
|
|
# Vérifier Node.js
|
|
try:
|
|
result = subprocess.run(['node', '--version'], capture_output=True, text=True)
|
|
if result.returncode == 0:
|
|
print(f"✅ Node.js OK ({result.stdout.strip()})")
|
|
else:
|
|
print("❌ Node.js non trouvé")
|
|
return False
|
|
except FileNotFoundError:
|
|
print("❌ Node.js non installé")
|
|
return False
|
|
|
|
# Vérifier les dépendances Python
|
|
required_packages = ['flask', 'flask-cors', 'pillow', 'numpy']
|
|
for package in required_packages:
|
|
try:
|
|
__import__(package.replace('-', '_'))
|
|
print(f"✅ {package} OK")
|
|
except ImportError:
|
|
print(f"❌ {package} manquant")
|
|
print(f"💡 Installez avec: pip install {package}")
|
|
return False
|
|
|
|
return True
|
|
|
|
def setup_environment(self):
|
|
"""
|
|
Configure l'environnement de développement
|
|
"""
|
|
print("⚙️ Configuration de l'environnement...")
|
|
|
|
# Créer les dossiers nécessaires
|
|
(self.base_path / "data" / "demo").mkdir(parents=True, exist_ok=True)
|
|
(self.base_path / "logs").mkdir(parents=True, exist_ok=True)
|
|
|
|
# Vérifier les fichiers de configuration
|
|
backend_env = self.base_path / "backend" / ".env"
|
|
if not backend_env.exists():
|
|
print("📝 Création du fichier .env backend...")
|
|
with open(backend_env, 'w') as f:
|
|
f.write("FLASK_ENV=development\n")
|
|
f.write("FLASK_DEBUG=True\n")
|
|
f.write("CORS_ORIGINS=http://localhost:3000\n")
|
|
|
|
print("✅ Environnement configuré")
|
|
|
|
def start_backend(self):
|
|
"""
|
|
Démarre le backend Flask
|
|
"""
|
|
print("🚀 Démarrage du backend Flask...")
|
|
|
|
backend_path = self.base_path / "backend"
|
|
|
|
# Démarrer le serveur Flask
|
|
process = subprocess.Popen(
|
|
[sys.executable, "app.py"],
|
|
cwd=backend_path,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
text=True
|
|
)
|
|
|
|
self.processes.append(('Backend Flask', process))
|
|
print("✅ Backend Flask démarré sur http://localhost:5002")
|
|
|
|
return process
|
|
|
|
def start_demo_server(self):
|
|
"""
|
|
Démarre le serveur de démonstration réelle
|
|
"""
|
|
print("🎭 Démarrage du serveur de démonstration...")
|
|
|
|
# Démarrer le serveur de démonstration
|
|
process = subprocess.Popen(
|
|
[sys.executable, "demo_real_functionality.py"],
|
|
cwd=self.base_path,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
text=True
|
|
)
|
|
|
|
self.processes.append(('Serveur Démonstration', process))
|
|
print("✅ Serveur de démonstration démarré sur http://localhost:5003")
|
|
|
|
return process
|
|
|
|
def start_frontend(self):
|
|
"""
|
|
Démarre le frontend React
|
|
"""
|
|
print("🎨 Démarrage du frontend React...")
|
|
|
|
frontend_path = self.base_path / "frontend"
|
|
|
|
# Vérifier si node_modules existe
|
|
if not (frontend_path / "node_modules").exists():
|
|
print("📦 Installation des dépendances npm...")
|
|
subprocess.run(["npm", "install"], cwd=frontend_path, check=True)
|
|
|
|
# Démarrer le serveur de développement
|
|
process = subprocess.Popen(
|
|
["npm", "start"],
|
|
cwd=frontend_path,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
text=True
|
|
)
|
|
|
|
self.processes.append(('Frontend React', process))
|
|
print("✅ Frontend React démarré sur http://localhost:3000")
|
|
|
|
return process
|
|
|
|
def wait_for_services(self):
|
|
"""
|
|
Attend que tous les services soient prêts
|
|
"""
|
|
print("⏳ Attente du démarrage des services...")
|
|
|
|
services = [
|
|
("Backend Flask", "http://localhost:5002/api/workflows"),
|
|
("Serveur Démonstration", "http://localhost:5003/api/demo/elements"),
|
|
("Frontend React", "http://localhost:3000")
|
|
]
|
|
|
|
try:
|
|
import requests
|
|
except ImportError:
|
|
print("⚠️ Module requests non disponible, vérification simplifiée")
|
|
time.sleep(10)
|
|
return
|
|
|
|
for service_name, url in services:
|
|
max_attempts = 30
|
|
for attempt in range(max_attempts):
|
|
try:
|
|
if "localhost:3000" in url:
|
|
# Pour le frontend, on vérifie juste la connexion TCP
|
|
import socket
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
result = sock.connect_ex(('localhost', 3000))
|
|
sock.close()
|
|
if result == 0:
|
|
print(f"✅ {service_name} prêt")
|
|
break
|
|
else:
|
|
response = requests.get(url, timeout=2)
|
|
if response.status_code < 500:
|
|
print(f"✅ {service_name} prêt")
|
|
break
|
|
except:
|
|
pass
|
|
|
|
if attempt < max_attempts - 1:
|
|
time.sleep(2)
|
|
else:
|
|
print(f"⚠️ {service_name} ne répond pas")
|
|
|
|
def launch_all_services(self):
|
|
"""
|
|
Lance tous les services nécessaires
|
|
"""
|
|
print("🚀 Lancement de tous les services...")
|
|
|
|
if not self.check_dependencies():
|
|
return False
|
|
|
|
self.setup_environment()
|
|
|
|
# Démarrer les services en arrière-plan
|
|
backend_process = self.start_backend()
|
|
demo_process = self.start_demo_server()
|
|
|
|
# Attendre un peu avant de démarrer le frontend
|
|
time.sleep(3)
|
|
|
|
frontend_process = self.start_frontend()
|
|
|
|
# Attendre que tous les services soient prêts
|
|
self.wait_for_services()
|
|
|
|
return True
|
|
|
|
def stop_all_services(self):
|
|
"""
|
|
Arrête tous les services
|
|
"""
|
|
print("🛑 Arrêt de tous les services...")
|
|
|
|
for service_name, process in self.processes:
|
|
try:
|
|
print(f"🛑 Arrêt de {service_name}...")
|
|
process.terminate()
|
|
process.wait(timeout=5)
|
|
except subprocess.TimeoutExpired:
|
|
print(f"⚠️ Forçage de l'arrêt de {service_name}...")
|
|
process.kill()
|
|
except Exception as e:
|
|
print(f"⚠️ Erreur lors de l'arrêt de {service_name}: {e}")
|
|
|
|
self.processes.clear()
|
|
self.is_running = False
|
|
print("✅ Tous les services arrêtés")
|
|
|
|
def show_demo_instructions(self):
|
|
"""
|
|
Affiche les instructions pour utiliser la démonstration
|
|
"""
|
|
print("\n" + "="*80)
|
|
print("🎭 DÉMONSTRATION RÉELLE DU VISUAL WORKFLOW BUILDER")
|
|
print("="*80)
|
|
print()
|
|
print("📋 Services disponibles:")
|
|
print(" • Frontend React: http://localhost:3000")
|
|
print(" • Backend API: http://localhost:5002")
|
|
print(" • Serveur Démonstration: http://localhost:5003")
|
|
print()
|
|
print("🎯 Comment utiliser la démonstration:")
|
|
print(" 1. Ouvrez votre navigateur sur http://localhost:3000")
|
|
print(" 2. Cliquez sur l'onglet 'Démonstration Réelle'")
|
|
print(" 3. Vous verrez votre écran en temps réel")
|
|
print(" 4. Cliquez sur les éléments détectés pour les tester")
|
|
print(" 5. Créez et exécutez des workflows de démonstration")
|
|
print()
|
|
print("🔧 Fonctionnalités disponibles:")
|
|
print(" • Capture d'écran en temps réel")
|
|
print(" • Détection d'éléments UI automatique")
|
|
print(" • Exécution d'actions réelles (clics, saisie)")
|
|
print(" • Workflows de démonstration")
|
|
print(" • Historique des exécutions")
|
|
print()
|
|
print("⚠️ Appuyez sur Ctrl+C pour arrêter tous les services")
|
|
print("="*80)
|
|
|
|
def main():
|
|
"""
|
|
Point d'entrée principal
|
|
"""
|
|
launcher = RealDemoLauncher()
|
|
|
|
def signal_handler(sig, frame):
|
|
print("\n🛑 Signal d'arrêt reçu...")
|
|
launcher.stop_all_services()
|
|
sys.exit(0)
|
|
|
|
# Gérer les signaux d'arrêt
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
signal.signal(signal.SIGTERM, signal_handler)
|
|
|
|
try:
|
|
if launcher.launch_all_services():
|
|
launcher.show_demo_instructions()
|
|
|
|
# Garder le script en vie
|
|
while launcher.is_running:
|
|
time.sleep(1)
|
|
else:
|
|
print("❌ Impossible de démarrer les services")
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur inattendue: {e}")
|
|
launcher.stop_all_services()
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main() |