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:
269
scripts/start_vwb_backend_ultra_stable.py
Executable file
269
scripts/start_vwb_backend_ultra_stable.py
Executable file
@@ -0,0 +1,269 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Script de Démarrage Backend VWB Ultra Stable
|
||||
Auteur : Dom, Alice, Kiro - 09 janvier 2026
|
||||
|
||||
Ce script démarre le backend VWB avec l'Option A (MSS ultra stable)
|
||||
et vérifie que tout fonctionne correctement.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
import requests
|
||||
import signal
|
||||
from pathlib import Path
|
||||
|
||||
# Configuration
|
||||
BACKEND_PORT = 5003
|
||||
BACKEND_SCRIPT = "visual_workflow_builder/backend/app_lightweight.py"
|
||||
HEALTH_URL = f"http://localhost:{BACKEND_PORT}/api/health"
|
||||
CAPTURE_URL = f"http://localhost:{BACKEND_PORT}/api/screen-capture"
|
||||
|
||||
def check_port_available(port):
|
||||
"""Vérifier si un port est disponible"""
|
||||
import socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(1)
|
||||
result = sock.connect_ex(('localhost', port))
|
||||
sock.close()
|
||||
return result != 0
|
||||
|
||||
def kill_existing_backend():
|
||||
"""Tuer les processus backend existants"""
|
||||
try:
|
||||
# Chercher les processus Python qui utilisent app_lightweight.py
|
||||
result = subprocess.run(['ps', 'aux'], capture_output=True, text=True)
|
||||
lines = result.stdout.split('\n')
|
||||
|
||||
for line in lines:
|
||||
if 'app_lightweight.py' in line and 'python' in line:
|
||||
# Extraire le PID
|
||||
parts = line.split()
|
||||
if len(parts) > 1:
|
||||
try:
|
||||
pid = int(parts[1])
|
||||
print(f"🔄 Arrêt du processus backend existant (PID: {pid})")
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
time.sleep(2)
|
||||
|
||||
# Vérifier si le processus est toujours là
|
||||
try:
|
||||
os.kill(pid, 0) # Test si le processus existe
|
||||
print(f"⚠️ Processus {pid} toujours actif, force kill...")
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
except ProcessLookupError:
|
||||
print(f"✅ Processus {pid} arrêté avec succès")
|
||||
|
||||
except (ValueError, ProcessLookupError):
|
||||
pass
|
||||
except Exception as e:
|
||||
print(f"⚠️ Erreur lors de l'arrêt des processus existants: {e}")
|
||||
|
||||
def start_backend():
|
||||
"""Démarrer le backend"""
|
||||
print(f"🚀 Démarrage du backend sur le port {BACKEND_PORT}...")
|
||||
|
||||
# Vérifier que le script existe
|
||||
if not os.path.exists(BACKEND_SCRIPT):
|
||||
print(f"❌ Script backend non trouvé: {BACKEND_SCRIPT}")
|
||||
return None
|
||||
|
||||
# Définir les variables d'environnement
|
||||
env = os.environ.copy()
|
||||
env['PORT'] = str(BACKEND_PORT)
|
||||
env['PYTHONPATH'] = os.getcwd()
|
||||
|
||||
# Démarrer le processus
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
[sys.executable, BACKEND_SCRIPT],
|
||||
env=env,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
universal_newlines=True,
|
||||
bufsize=1
|
||||
)
|
||||
|
||||
print(f"✅ Backend démarré (PID: {process.pid})")
|
||||
return process
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur lors du démarrage: {e}")
|
||||
return None
|
||||
|
||||
def wait_for_backend(timeout=30):
|
||||
"""Attendre que le backend soit prêt"""
|
||||
print(f"⏳ Attente de la disponibilité du backend (timeout: {timeout}s)...")
|
||||
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < timeout:
|
||||
try:
|
||||
response = requests.get(HEALTH_URL, timeout=2)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"✅ Backend prêt - Version: {data.get('version')}")
|
||||
print(f" Features: screen_capture={data.get('features', {}).get('screen_capture')}")
|
||||
print(f" Features: visual_embedding={data.get('features', {}).get('visual_embedding')}")
|
||||
return True
|
||||
except requests.exceptions.RequestException:
|
||||
pass
|
||||
|
||||
time.sleep(1)
|
||||
print(".", end="", flush=True)
|
||||
|
||||
print(f"\n❌ Backend non disponible après {timeout}s")
|
||||
return False
|
||||
|
||||
def test_capture():
|
||||
"""Tester la capture d'écran"""
|
||||
print("🔍 Test de la capture d'écran...")
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
CAPTURE_URL,
|
||||
json={"format": "png", "quality": 90},
|
||||
headers={'Content-Type': 'application/json'},
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get('success'):
|
||||
print(f"✅ Capture réussie - {data.get('width')}x{data.get('height')} ({data.get('method')})")
|
||||
|
||||
# Vérifier que c'est bien l'Option A
|
||||
if data.get('method') == 'ultra_stable_mss':
|
||||
print("✅ Option A (ultra_stable_mss) confirmée")
|
||||
return True
|
||||
else:
|
||||
print(f"⚠️ Méthode inattendue: {data.get('method')}")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ Capture échouée: {data.get('error')}")
|
||||
return False
|
||||
else:
|
||||
print(f"❌ Erreur HTTP {response.status_code}: {response.text}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur test capture: {e}")
|
||||
return False
|
||||
|
||||
def show_status():
|
||||
"""Afficher le statut du système"""
|
||||
print("\n" + "="*60)
|
||||
print(" STATUT DU SYSTÈME VWB")
|
||||
print("="*60)
|
||||
|
||||
# Vérifier le backend
|
||||
try:
|
||||
response = requests.get(HEALTH_URL, timeout=2)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
print(f"✅ Backend: ACTIF (port {BACKEND_PORT})")
|
||||
print(f" Version: {data.get('version')}")
|
||||
print(f" Mode: {data.get('mode')}")
|
||||
else:
|
||||
print(f"❌ Backend: ERREUR (HTTP {response.status_code})")
|
||||
except:
|
||||
print(f"❌ Backend: INACCESSIBLE (port {BACKEND_PORT})")
|
||||
|
||||
# Vérifier le frontend
|
||||
try:
|
||||
response = requests.get("http://localhost:3000", timeout=2)
|
||||
if response.status_code == 200:
|
||||
print("✅ Frontend: ACTIF (port 3000)")
|
||||
else:
|
||||
print(f"❌ Frontend: ERREUR (HTTP {response.status_code})")
|
||||
except:
|
||||
print("❌ Frontend: INACCESSIBLE (port 3000)")
|
||||
|
||||
print("\n🌐 URLs importantes:")
|
||||
print(f" Backend API: http://localhost:{BACKEND_PORT}/api")
|
||||
print(f" Health Check: {HEALTH_URL}")
|
||||
print(f" Capture API: {CAPTURE_URL}")
|
||||
print(f" Frontend: http://localhost:3000")
|
||||
print(f" Test Simple: file://{os.path.abspath('visual_workflow_builder/test_capture_simple.html')}")
|
||||
|
||||
def main():
|
||||
"""Fonction principale"""
|
||||
print("="*60)
|
||||
print(" DÉMARRAGE BACKEND VWB ULTRA STABLE")
|
||||
print("="*60)
|
||||
print("Auteur : Dom, Alice, Kiro - 09 janvier 2026")
|
||||
print(f"Port: {BACKEND_PORT}")
|
||||
print(f"Script: {BACKEND_SCRIPT}")
|
||||
print("")
|
||||
|
||||
# Étape 1: Vérifier si le port est libre
|
||||
if not check_port_available(BACKEND_PORT):
|
||||
print(f"⚠️ Port {BACKEND_PORT} occupé - Arrêt des processus existants...")
|
||||
kill_existing_backend()
|
||||
time.sleep(3)
|
||||
|
||||
if not check_port_available(BACKEND_PORT):
|
||||
print(f"❌ Port {BACKEND_PORT} toujours occupé")
|
||||
return False
|
||||
|
||||
# Étape 2: Démarrer le backend
|
||||
process = start_backend()
|
||||
if not process:
|
||||
return False
|
||||
|
||||
try:
|
||||
# Étape 3: Attendre que le backend soit prêt
|
||||
if not wait_for_backend():
|
||||
print("❌ Backend non disponible")
|
||||
process.terminate()
|
||||
return False
|
||||
|
||||
# Étape 4: Tester la capture
|
||||
if not test_capture():
|
||||
print("❌ Test de capture échoué")
|
||||
process.terminate()
|
||||
return False
|
||||
|
||||
# Étape 5: Afficher le statut
|
||||
show_status()
|
||||
|
||||
print("\n🎉 BACKEND DÉMARRÉ AVEC SUCCÈS !")
|
||||
print("✅ Option A (ultra stable) opérationnelle")
|
||||
print("✅ Capture d'écran fonctionnelle")
|
||||
print("✅ Prêt pour les connexions frontend")
|
||||
|
||||
print(f"\n🔧 Le backend fonctionne en arrière-plan (PID: {process.pid})")
|
||||
print(" Pour l'arrêter: Ctrl+C ou kill le processus")
|
||||
print(" Pour tester: Ouvrez visual_workflow_builder/test_capture_simple.html")
|
||||
|
||||
# Garder le processus en vie
|
||||
try:
|
||||
while True:
|
||||
time.sleep(10)
|
||||
# Vérifier que le processus est toujours vivant
|
||||
if process.poll() is not None:
|
||||
print("❌ Le processus backend s'est arrêté")
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
print("\n🛑 Arrêt demandé par l'utilisateur")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur: {e}")
|
||||
return False
|
||||
|
||||
finally:
|
||||
if process and process.poll() is None:
|
||||
print("🔄 Arrêt du backend...")
|
||||
process.terminate()
|
||||
time.sleep(2)
|
||||
if process.poll() is None:
|
||||
process.kill()
|
||||
print("✅ Backend arrêté")
|
||||
|
||||
if __name__ == "__main__":
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user