Files
rpa_vision_v3/diagnostic_backend_complet.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

296 lines
11 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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())