- 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>
187 lines
5.9 KiB
Python
187 lines
5.9 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Script de démarrage propre du backend VWB
|
||
Auteur : Dom, Alice, Kiro - 8 janvier 2026
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import subprocess
|
||
import time
|
||
import signal
|
||
import psutil
|
||
|
||
def nettoyer_processus_backend():
|
||
"""Nettoyer tous les processus backend existants"""
|
||
print("🧹 Nettoyage des processus backend existants...")
|
||
|
||
processus_tues = 0
|
||
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
|
||
try:
|
||
cmdline = ' '.join(proc.info['cmdline'] or [])
|
||
if any(pattern in cmdline for pattern in [
|
||
'visual_workflow_builder/backend/app.py',
|
||
'web_dashboard/app.py',
|
||
'flask',
|
||
':5001',
|
||
':5002'
|
||
]):
|
||
print(f" 🔪 Arrêt du processus PID {proc.info['pid']}: {proc.info['name']}")
|
||
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(3) # Attendre que les processus se terminent proprement
|
||
else:
|
||
print(" ℹ️ Aucun processus backend trouvé")
|
||
|
||
def verifier_port_libre(port):
|
||
"""Vérifier si un port est libre"""
|
||
import socket
|
||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||
try:
|
||
s.bind(('localhost', port))
|
||
return True
|
||
except OSError:
|
||
return False
|
||
|
||
def demarrer_backend():
|
||
"""Démarrer le backend VWB proprement"""
|
||
print("🚀 Démarrage du backend VWB...")
|
||
|
||
# Vérifier que le port 5002 est libre
|
||
if not verifier_port_libre(5002):
|
||
print("❌ Le port 5002 est occupé")
|
||
return None
|
||
|
||
# Variables d'environnement propres
|
||
env = os.environ.copy()
|
||
env.update({
|
||
'PORT': '5002',
|
||
'FLASK_ENV': 'development',
|
||
'FLASK_DEBUG': '1',
|
||
'PYTHONPATH': '.',
|
||
})
|
||
|
||
# Supprimer les variables qui pourraient causer des conflits
|
||
for var in ['FLASK_APP', 'FLASK_RUN_PORT', 'FLASK_RUN_HOST']:
|
||
env.pop(var, None)
|
||
|
||
# Commande de démarrage
|
||
cmd = [
|
||
'./venv_v3/bin/python',
|
||
'visual_workflow_builder/backend/app.py'
|
||
]
|
||
|
||
try:
|
||
print(f" 📝 Commande: {' '.join(cmd)}")
|
||
print(f" 🔧 Port: 5002")
|
||
print(f" 🌍 Environnement: development")
|
||
|
||
# Démarrer le processus
|
||
process = subprocess.Popen(
|
||
cmd,
|
||
stdout=subprocess.PIPE,
|
||
stderr=subprocess.STDOUT,
|
||
env=env,
|
||
cwd='.',
|
||
bufsize=1,
|
||
universal_newlines=True
|
||
)
|
||
|
||
print(f" 🆔 PID: {process.pid}")
|
||
|
||
# Surveiller le démarrage
|
||
print(" ⏳ Surveillance du démarrage...")
|
||
|
||
for i in range(30): # 30 secondes max
|
||
# Vérifier si le processus est encore vivant
|
||
if process.poll() is not None:
|
||
stdout, stderr = process.communicate()
|
||
print(f" ❌ Le processus s'est arrêté prématurément")
|
||
print(f" 📝 Sortie: {stdout}")
|
||
return None
|
||
|
||
# Lire la sortie
|
||
try:
|
||
line = process.stdout.readline()
|
||
if line:
|
||
print(f" 📄 {line.strip()}")
|
||
|
||
# Vérifier les indicateurs de succès
|
||
if any(indicator in line.lower() for indicator in [
|
||
'running on',
|
||
'serving flask app',
|
||
'debug mode: on'
|
||
]):
|
||
print(f" ✅ Backend démarré avec succès !")
|
||
return process
|
||
|
||
# Vérifier les erreurs
|
||
if any(error in line.lower() for error in [
|
||
'error',
|
||
'failed',
|
||
'exception',
|
||
'address already in use'
|
||
]):
|
||
print(f" ❌ Erreur détectée: {line.strip()}")
|
||
process.terminate()
|
||
return None
|
||
|
||
except:
|
||
pass
|
||
|
||
time.sleep(1)
|
||
|
||
print(" ⚠️ Timeout atteint, mais le processus semble fonctionner")
|
||
return process
|
||
|
||
except Exception as e:
|
||
print(f" ❌ Erreur lors du démarrage: {e}")
|
||
return None
|
||
|
||
def main():
|
||
"""Fonction principale"""
|
||
print("🏥 DÉMARRAGE PROPRE DU BACKEND VWB")
|
||
print("=" * 50)
|
||
|
||
try:
|
||
# Étape 1: Nettoyer les processus existants
|
||
nettoyer_processus_backend()
|
||
|
||
# Étape 2: Démarrer le backend
|
||
process = demarrer_backend()
|
||
|
||
if process:
|
||
print("\n✅ Backend démarré avec succès !")
|
||
print(f"🔗 URL: http://localhost:5002")
|
||
print(f"🆔 PID: {process.pid}")
|
||
print("\n📋 Commandes utiles:")
|
||
print(f" • Tester: python3 visual_workflow_builder/quick_api_test.py")
|
||
print(f" • Arrêter: kill {process.pid}")
|
||
print("\n⌨️ Appuyez sur Ctrl+C pour arrêter le serveur")
|
||
|
||
# Attendre l'interruption
|
||
try:
|
||
process.wait()
|
||
except KeyboardInterrupt:
|
||
print("\n🛑 Arrêt demandé par l'utilisateur")
|
||
process.terminate()
|
||
process.wait()
|
||
print("✅ Backend arrêté proprement")
|
||
|
||
else:
|
||
print("\n❌ Échec du démarrage du backend")
|
||
return 1
|
||
|
||
except Exception as e:
|
||
print(f"\n💥 Erreur critique: {e}")
|
||
return 2
|
||
|
||
return 0
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main()) |