#!/usr/bin/env python3 """ Diagnostic et réparation complète du backend VWB Auteur : Dom, Alice, Kiro - 8 janvier 2026 """ import os import sys import subprocess import requests import time import json import psutil from pathlib import Path class DiagnosticBackend: """Classe pour diagnostiquer et réparer le backend VWB""" def __init__(self): self.backend_port = 5002 self.backend_url = f'http://localhost:{self.backend_port}' self.backend_path = 'visual_workflow_builder/backend' self.venv_path = './venv_v3' def verifier_environnement(self): """Vérifier l'environnement Python et les dépendances""" print("🔍 Vérification de l'environnement...") # Vérifier Python try: python_version = sys.version_info print(f" ✅ Python {python_version.major}.{python_version.minor}.{python_version.micro}") except Exception as e: print(f" ❌ Problème Python: {e}") return False # Vérifier l'environnement virtuel if os.path.exists(self.venv_path): print(f" ✅ Environnement virtuel trouvé: {self.venv_path}") else: print(f" ❌ Environnement virtuel manquant: {self.venv_path}") return False # Vérifier les dépendances critiques dependances_critiques = ['flask', 'flask_cors', 'flask_socketio', 'requests'] for dep in dependances_critiques: try: __import__(dep) print(f" ✅ Dépendance {dep} disponible") except ImportError: print(f" ❌ Dépendance {dep} manquante") return False return True def nettoyer_processus_existants(self): """Nettoyer les processus backend existants""" print("🧹 Nettoyage des processus existants...") processus_tues = 0 for proc in psutil.process_iter(['pid', 'name', 'cmdline']): try: cmdline = ' '.join(proc.info['cmdline'] or []) if 'visual_workflow_builder/backend/app.py' in cmdline: print(f" 🔪 Arrêt du processus PID {proc.info['pid']}") proc.terminate() processus_tues += 1 except (psutil.NoSuchProcess, psutil.AccessDenied): continue if processus_tues > 0: print(f" ✅ {processus_tues} processus arrêtés") time.sleep(2) # Attendre que les processus se terminent else: print(" ℹ️ Aucun processus backend en cours") return True def verifier_fichiers_backend(self): """Vérifier l'intégrité des fichiers backend""" print("📁 Vérification des fichiers backend...") fichiers_critiques = [ 'visual_workflow_builder/backend/app.py', 'visual_workflow_builder/backend/api/__init__.py', 'visual_workflow_builder/backend/api/workflows.py', 'visual_workflow_builder/backend/api/screen_capture.py', ] for fichier in fichiers_critiques: if os.path.exists(fichier): taille = os.path.getsize(fichier) print(f" ✅ {fichier} ({taille} bytes)") else: print(f" ❌ {fichier} manquant") return False return True def demarrer_backend(self): """Démarrer le backend en mode diagnostic""" print("🚀 Démarrage du backend...") # Commande pour démarrer le backend cmd = [ f'{self.venv_path}/bin/python', 'visual_workflow_builder/backend/app.py' ] try: # Démarrer en arrière-plan process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd='.', env=dict(os.environ, FLASK_ENV='development') ) print(f" 🔄 Processus démarré (PID: {process.pid})") # Attendre que le serveur démarre for tentative in range(10): try: response = requests.get(f'{self.backend_url}/health', timeout=2) if response.status_code == 200: print(f" ✅ Backend démarré avec succès sur le port {self.backend_port}") return process except requests.exceptions.ConnectionError: pass print(f" ⏳ Tentative {tentative + 1}/10...") time.sleep(2) # Si on arrive ici, le démarrage a échoué stdout, stderr = process.communicate(timeout=5) print(f" ❌ Échec du démarrage") print(f" 📝 STDOUT: {stdout.decode()}") print(f" 📝 STDERR: {stderr.decode()}") return None except Exception as e: print(f" ❌ Erreur lors du démarrage: {e}") return None def tester_endpoints(self): """Tester tous les endpoints critiques""" print("🧪 Test des endpoints critiques...") endpoints = [ ('/health', 'GET', None), ('/api/workflows/', 'GET', None), ('/api/screen-capture/', 'POST', {}), ] resultats = {} for endpoint, methode, data in endpoints: try: url = f'{self.backend_url}{endpoint}' if methode == 'GET': response = requests.get(url, timeout=10) elif methode == 'POST': response = requests.post(url, json=data, timeout=10) resultats[endpoint] = { 'status': response.status_code, 'success': response.status_code < 400 } status_icon = "✅" if response.status_code < 400 else "❌" print(f" {status_icon} {methode} {endpoint}: {response.status_code}") except Exception as e: resultats[endpoint] = { 'status': 'ERREUR', 'success': False, 'error': str(e) } print(f" ❌ {methode} {endpoint}: ERREUR - {e}") return resultats def generer_rapport(self, resultats_tests): """Générer un rapport de diagnostic""" print("\n" + "=" * 60) print("📊 RAPPORT DE DIAGNOSTIC BACKEND") print("=" * 60) total_tests = len(resultats_tests) tests_reussis = sum(1 for r in resultats_tests.values() if r['success']) taux_reussite = (tests_reussis / total_tests) * 100 if total_tests > 0 else 0 print(f"📈 Taux de réussite: {tests_reussis}/{total_tests} ({taux_reussite:.1f}%)") if taux_reussite == 100: print("🎉 Backend entièrement fonctionnel !") statut = "EXCELLENT" elif taux_reussite >= 70: print("⚠️ Backend partiellement fonctionnel") statut = "ACCEPTABLE" else: print("🚨 Backend défaillant") statut = "CRITIQUE" # Sauvegarder le rapport rapport = { 'timestamp': time.time(), 'statut': statut, 'taux_reussite': taux_reussite, 'tests': resultats_tests, 'recommandations': self.generer_recommandations(resultats_tests) } with open('diagnostic_backend_rapport.json', 'w', encoding='utf-8') as f: json.dump(rapport, f, indent=2, ensure_ascii=False) print(f"📄 Rapport sauvegardé: diagnostic_backend_rapport.json") return statut def generer_recommandations(self, resultats_tests): """Générer des recommandations basées sur les résultats""" recommandations = [] for endpoint, resultat in resultats_tests.items(): if not resultat['success']: if endpoint == '/health': recommandations.append("Vérifier la configuration Flask de base") elif endpoint == '/api/workflows/': recommandations.append("Vérifier la base de données et les modèles") elif endpoint == '/api/screen-capture/': recommandations.append("Vérifier les dépendances de capture d'écran") if not recommandations: recommandations.append("Backend fonctionnel - aucune action requise") return recommandations def executer_diagnostic_complet(self): """Exécuter le diagnostic complet""" print("🏥 DIAGNOSTIC COMPLET DU BACKEND VWB") print("=" * 50) # Étape 1: Vérifier l'environnement if not self.verifier_environnement(): print("❌ Environnement défaillant - arrêt du diagnostic") return False # Étape 2: Nettoyer les processus existants self.nettoyer_processus_existants() # Étape 3: Vérifier les fichiers if not self.verifier_fichiers_backend(): print("❌ Fichiers backend manquants - arrêt du diagnostic") return False # Étape 4: Démarrer le backend process = self.demarrer_backend() if not process: print("❌ Impossible de démarrer le backend") return False try: # Étape 5: Tester les endpoints resultats_tests = self.tester_endpoints() # Étape 6: Générer le rapport statut = self.generer_rapport(resultats_tests) return statut in ['EXCELLENT', 'ACCEPTABLE'] finally: # Nettoyer le processus de test if process and process.poll() is None: print("🧹 Nettoyage du processus de test...") process.terminate() def main(): """Fonction principale""" diagnostic = DiagnosticBackend() try: succes = diagnostic.executer_diagnostic_complet() exit_code = 0 if succes else 1 print(f"\n🏁 Diagnostic terminé (code de sortie: {exit_code})") return exit_code except KeyboardInterrupt: print("\n⚠️ Diagnostic interrompu par l'utilisateur") return 2 except Exception as e: print(f"\n❌ Erreur critique lors du diagnostic: {e}") return 3 if __name__ == "__main__": sys.exit(main())