Files
rpa_vision_v3/diagnostic_et_correction_vwb.py
Dom a27b74cf22 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>
2026-01-29 11:23:51 +01:00

356 lines
14 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Diagnostic et Correction VWB
Auteur : Dom, Alice, Kiro - 8 janvier 2026
Ce script diagnostique et corrige les problèmes du Visual Workflow Builder.
"""
import subprocess
import time
import requests
import signal
import os
import sys
from typing import Optional, Tuple
class Colors:
RED = '\033[0;31m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
BLUE = '\033[0;34m'
PURPLE = '\033[0;35m'
CYAN = '\033[0;36m'
BOLD = '\033[1m'
NC = '\033[0m'
class VWBDiagnostic:
def __init__(self):
self.original_dir = os.getcwd()
self.vwb_dir = os.path.join(self.original_dir, "visual_workflow_builder")
self.backend_dir = os.path.join(self.vwb_dir, "backend")
self.frontend_dir = os.path.join(self.vwb_dir, "frontend")
def print_header(self):
"""Affiche l'en-tête du diagnostic"""
print(f"{Colors.PURPLE}{Colors.BOLD}")
print("╔════════════════════════════════════════════════════════════╗")
print("║ 🔧 Diagnostic et Correction VWB ║")
print("║ Auteur : Dom, Alice, Kiro - 8 janvier 2026 ║")
print("╚════════════════════════════════════════════════════════════╝")
print(f"{Colors.NC}")
def check_directories(self) -> bool:
"""Vérifie que les répertoires existent"""
print(f"\n{Colors.BLUE}[1/6] Vérification des répertoires{Colors.NC}")
print("=" * 50)
success = True
directories = [
(self.vwb_dir, "Visual Workflow Builder"),
(self.backend_dir, "Backend"),
(self.frontend_dir, "Frontend")
]
for dir_path, name in directories:
if os.path.exists(dir_path):
print(f"{Colors.GREEN}{name} : {dir_path}{Colors.NC}")
else:
print(f"{Colors.RED}{name} manquant : {dir_path}{Colors.NC}")
success = False
return success
def check_dependencies(self) -> bool:
"""Vérifie les dépendances"""
print(f"\n{Colors.BLUE}[2/6] Vérification des dépendances{Colors.NC}")
print("=" * 50)
success = True
# Vérifier Python et l'environnement virtuel
try:
result = subprocess.run(
["source", "venv_v3/bin/activate", "&&", "python3", "--version"],
shell=True, capture_output=True, text=True
)
if result.returncode == 0:
print(f"{Colors.GREEN}✅ Python avec venv_v3 : {result.stdout.strip()}{Colors.NC}")
else:
print(f"{Colors.RED}❌ Problème avec l'environnement virtuel{Colors.NC}")
success = False
except Exception as e:
print(f"{Colors.RED}❌ Erreur Python : {e}{Colors.NC}")
success = False
# Vérifier Node.js
try:
result = subprocess.run(["node", "--version"], capture_output=True, text=True)
if result.returncode == 0:
print(f"{Colors.GREEN}✅ Node.js : {result.stdout.strip()}{Colors.NC}")
else:
print(f"{Colors.RED}❌ Node.js non trouvé{Colors.NC}")
success = False
except Exception as e:
print(f"{Colors.RED}❌ Erreur Node.js : {e}{Colors.NC}")
success = False
return success
def cleanup_ports(self) -> bool:
"""Nettoie les ports utilisés"""
print(f"\n{Colors.BLUE}[3/6] Nettoyage des ports{Colors.NC}")
print("=" * 50)
ports = [3000, 5002]
cleaned = False
for port in ports:
try:
result = subprocess.run(
f"lsof -ti:{port} | xargs -r kill -9",
shell=True, capture_output=True
)
if result.returncode == 0:
print(f"{Colors.YELLOW}🧹 Port {port} nettoyé{Colors.NC}")
cleaned = True
else:
print(f"{Colors.GREEN}✅ Port {port} libre{Colors.NC}")
except Exception as e:
print(f"{Colors.YELLOW}⚠️ Erreur nettoyage port {port} : {e}{Colors.NC}")
if cleaned:
time.sleep(2) # Attendre que les ports se libèrent
return True
def start_backend(self) -> Tuple[bool, Optional[subprocess.Popen]]:
"""Démarre le backend"""
print(f"\n{Colors.BLUE}[4/6] Démarrage du backend{Colors.NC}")
print("=" * 50)
try:
os.chdir(self.backend_dir)
# Commande pour démarrer le backend
cmd = [
"bash", "-c",
"source ../../../venv_v3/bin/activate && python3 app.py"
]
print(f"{Colors.CYAN}🚀 Lancement du backend Flask...{Colors.NC}")
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
preexec_fn=os.setsid
)
# Attendre que le backend soit prêt
start_time = time.time()
timeout = 30
while time.time() - start_time < timeout:
try:
response = requests.get("http://localhost:5002/health", timeout=2)
if response.status_code == 200:
print(f"{Colors.GREEN}✅ Backend prêt sur http://localhost:5002{Colors.NC}")
os.chdir(self.original_dir)
return True, process
except requests.exceptions.RequestException:
pass
# Vérifier si le processus est encore en vie
if process.poll() is not None:
stdout, stderr = process.communicate()
print(f"{Colors.RED}❌ Le backend s'est arrêté{Colors.NC}")
print(f"STDERR: {stderr.decode()[-500:]}") # Derniers 500 caractères
os.chdir(self.original_dir)
return False, None
time.sleep(1)
print(f"{Colors.RED}❌ Timeout: Le backend n'a pas démarré en {timeout}s{Colors.NC}")
os.chdir(self.original_dir)
return False, process
except Exception as e:
print(f"{Colors.RED}❌ Erreur lors du démarrage du backend : {e}{Colors.NC}")
os.chdir(self.original_dir)
return False, None
def start_frontend(self) -> Tuple[bool, Optional[subprocess.Popen]]:
"""Démarre le frontend"""
print(f"\n{Colors.BLUE}[5/6] Démarrage du frontend{Colors.NC}")
print("=" * 50)
try:
os.chdir(self.frontend_dir)
# Vérifier si node_modules existe
if not os.path.exists("node_modules"):
print(f"{Colors.YELLOW}📦 Installation des dépendances npm...{Colors.NC}")
result = subprocess.run(["npm", "install"], capture_output=True, text=True)
if result.returncode != 0:
print(f"{Colors.RED}❌ Erreur lors de l'installation npm{Colors.NC}")
os.chdir(self.original_dir)
return False, None
print(f"{Colors.CYAN}🎨 Lancement du serveur React...{Colors.NC}")
# Démarrer le frontend
env = os.environ.copy()
env['BROWSER'] = 'none' # Ne pas ouvrir le navigateur automatiquement
process = subprocess.Popen(
["npm", "start"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
preexec_fn=os.setsid
)
# Attendre que le frontend soit prêt
start_time = time.time()
timeout = 60
while time.time() - start_time < timeout:
try:
response = requests.get("http://localhost:3000", timeout=2)
if response.status_code in [200, 404]: # 404 est OK pour React
print(f"{Colors.GREEN}✅ Frontend prêt sur http://localhost:3000{Colors.NC}")
os.chdir(self.original_dir)
return True, process
except requests.exceptions.RequestException:
pass
# Vérifier si le processus est encore en vie
if process.poll() is not None:
stdout, stderr = process.communicate()
print(f"{Colors.RED}❌ Le frontend s'est arrêté{Colors.NC}")
print(f"STDERR: {stderr.decode()[-500:]}")
os.chdir(self.original_dir)
return False, None
time.sleep(2)
print(f"{Colors.RED}❌ Timeout: Le frontend n'a pas démarré en {timeout}s{Colors.NC}")
os.chdir(self.original_dir)
return False, process
except Exception as e:
print(f"{Colors.RED}❌ Erreur lors du démarrage du frontend : {e}{Colors.NC}")
os.chdir(self.original_dir)
return False, None
def test_integration(self) -> bool:
"""Teste l'intégration frontend-backend"""
print(f"\n{Colors.BLUE}[6/6] Test d'intégration{Colors.NC}")
print("=" * 50)
success = True
# Tester les endpoints du backend
backend_endpoints = [
("/health", "Health Check"),
("/api/workflows", "Workflows API"),
("/api/node-types", "Node Types API")
]
for endpoint, description in backend_endpoints:
try:
response = requests.get(f"http://localhost:5002{endpoint}", timeout=5)
if response.status_code in [200, 404, 405]:
print(f"{Colors.GREEN}{description}: {endpoint} (status: {response.status_code}){Colors.NC}")
else:
print(f"{Colors.YELLOW}⚠️ {description}: {endpoint} (status: {response.status_code}){Colors.NC}")
except Exception as e:
print(f"{Colors.RED}{description}: {endpoint} - Erreur: {e}{Colors.NC}")
success = False
# Tester le frontend
try:
response = requests.get("http://localhost:3000", timeout=5)
if response.status_code == 200:
print(f"{Colors.GREEN}✅ Frontend accessible{Colors.NC}")
else:
print(f"{Colors.YELLOW}⚠️ Frontend status: {response.status_code}{Colors.NC}")
except Exception as e:
print(f"{Colors.RED}❌ Frontend non accessible : {e}{Colors.NC}")
success = False
return success
def run_diagnostic(self) -> bool:
"""Exécute le diagnostic complet"""
self.print_header()
# Étapes du diagnostic
if not self.check_directories():
return False
if not self.check_dependencies():
return False
self.cleanup_ports()
backend_success, backend_process = self.start_backend()
if not backend_success:
return False
frontend_success, frontend_process = self.start_frontend()
if not frontend_success:
if backend_process:
try:
os.killpg(os.getpgid(backend_process.pid), signal.SIGTERM)
except:
pass
return False
integration_success = self.test_integration()
# Afficher le résumé
print(f"\n{Colors.PURPLE}{Colors.BOLD}📊 RÉSUMÉ DU DIAGNOSTIC{Colors.NC}")
print("=" * 60)
if backend_success and frontend_success and integration_success:
print(f"{Colors.GREEN}{Colors.BOLD}🎉 VISUAL WORKFLOW BUILDER OPÉRATIONNEL !{Colors.NC}")
print(f"\n{Colors.CYAN}URLs d'accès :{Colors.NC}")
print(f" Frontend: http://localhost:3000")
print(f" Backend: http://localhost:5002")
print(f"\n{Colors.YELLOW}Les services restent en cours d'exécution.{Colors.NC}")
print(f"{Colors.YELLOW}Appuyez sur Ctrl+C pour les arrêter.{Colors.NC}")
# Garder les services en vie
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print(f"\n{Colors.YELLOW}🛑 Arrêt des services...{Colors.NC}")
if backend_process:
try:
os.killpg(os.getpgid(backend_process.pid), signal.SIGTERM)
except:
pass
if frontend_process:
try:
os.killpg(os.getpgid(frontend_process.pid), signal.SIGTERM)
except:
pass
print(f"{Colors.GREEN}✓ Services arrêtés{Colors.NC}")
return True
else:
print(f"{Colors.RED}{Colors.BOLD}❌ PROBLÈMES DÉTECTÉS{Colors.NC}")
return False
def main():
"""Fonction principale"""
diagnostic = VWBDiagnostic()
success = diagnostic.run_diagnostic()
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()