v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- 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>
This commit is contained in:
308
visual_workflow_builder/start_real_demo.py
Normal file
308
visual_workflow_builder/start_real_demo.py
Normal file
@@ -0,0 +1,308 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user