#!/usr/bin/env python3 """ Démarre le serveur API local pour le développement sur un port libre. """ import os import sys import time import subprocess import requests import tempfile import shutil from pathlib import Path def load_env_local(): """Charge les variables d'environnement depuis .env.local""" env_path = Path(".env.local") if not env_path.exists(): print("❌ Fichier .env.local non trouvé") return False print(f"📁 Chargement de {env_path}") with open(env_path, 'r') as f: for line in f: line = line.strip() if line and not line.startswith('#') and '=' in line: key, value = line.split('=', 1) os.environ[key.strip()] = value.strip() if key.strip() in ['RPA_TOKEN_ADMIN', 'RPA_TOKEN_READONLY']: print(f" ✓ {key.strip()}: {value.strip()[:16]}...") return True def find_free_port(start_port=8001): """Trouve un port libre""" import socket for port in range(start_port, start_port + 10): try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind(('127.0.0.1', port)) return port except OSError: continue return None def create_dev_server_script(port): """Crée un script serveur temporaire avec le bon port""" server_dir = Path("server") original_script = server_dir / "api_upload.py" if not original_script.exists(): print("❌ Fichier server/api_upload.py non trouvé") return None # Lire le script original with open(original_script, 'r') as f: content = f.read() # Remplacer le port hardcodé modified_content = content.replace( 'port=8000,', f'port={port},' ) # Créer un fichier temporaire temp_script = server_dir / f"api_upload_dev_{port}.py" with open(temp_script, 'w') as f: f.write(modified_content) print(f"✓ Script serveur temporaire créé: {temp_script}") return temp_script def start_dev_server(): """Démarre le serveur de développement""" print("🚀 === DÉMARRAGE SERVEUR DÉVELOPPEMENT ===") # Charger les variables d'environnement if not load_env_local(): return False # Trouver un port libre port = find_free_port(8001) if not port: print("❌ Aucun port libre trouvé") return False print(f"🌐 Port sélectionné: {port}") # Créer le script serveur temporaire temp_script = create_dev_server_script(port) if not temp_script: return False try: # Démarrer le serveur avec l'environnement virtuel venv_python = Path("venv_v3/bin/python3") if not venv_python.exists(): print("❌ Environnement virtuel venv_v3 non trouvé") return False print(f"🚀 Démarrage du serveur sur le port {port}...") # Démarrer en arrière-plan process = subprocess.Popen([ str(venv_python.absolute()), temp_script.name ], cwd="server", env=os.environ.copy()) print(f" PID: {process.pid}") print(f" URL: http://127.0.0.1:{port}") # Attendre que le serveur démarre print("⏳ Attente du démarrage du serveur...") for i in range(20): time.sleep(1) try: response = requests.get(f"http://127.0.0.1:{port}/health", timeout=2) if response.status_code in [200, 401]: # 401 = serveur répond mais auth requise print("✅ Serveur démarré!") break except requests.exceptions.ConnectionError: if i == 19: print("❌ Serveur n'a pas démarré dans les temps") process.terminate() return False print(f" Tentative {i+1}/20...") # Tester l'authentification print("🔐 Test d'authentification...") token = os.environ.get('RPA_TOKEN_ADMIN') try: response = requests.get( f"http://127.0.0.1:{port}/api/traces/status", headers={"Authorization": f"Bearer {token}"}, timeout=5 ) if response.status_code == 200: print("✅ Authentification réussie!") # Tester l'upload avec le bon format print("🧪 Test d'upload...") test_data = b"test upload data" files = { "file": ("test_session.zip", test_data, "application/zip") } data = { "session_id": "test_session_123" } upload_response = requests.post( f"http://127.0.0.1:{port}/api/traces/upload", headers={"Authorization": f"Bearer {token}"}, files=files, data=data, timeout=10 ) if upload_response.status_code == 200: print("✅ Upload test réussi!") # Mettre à jour .env.local avec la nouvelle URL update_env_server_url(f"http://127.0.0.1:{port}/api/traces/upload") # Sauvegarder les informations du serveur save_server_info(process.pid, port, temp_script) print("\\n🎉 === SERVEUR DÉVELOPPEMENT PRÊT ===") print(f"✅ URL: http://127.0.0.1:{port}") print(f"✅ PID: {process.pid}") print(f"✅ Token: {token[:16]}...") print("\\n📝 PROCHAINES ÉTAPES:") print("1. Démarrer l'agent v0: cd agent_v0 && python main.py") print("2. Capturer une session de test") print("3. Vérifier que l'upload fonctionne") print(f"\\n🛑 Pour arrêter: python3 stop_dev_server.py") return True else: print(f"❌ Upload test échoué: {upload_response.status_code}") print(f" Réponse: {upload_response.text}") else: print(f"❌ Authentification échouée: {response.status_code}") print(f" Réponse: {response.text}") except Exception as e: print(f"❌ Erreur test: {e}") # Nettoyer en cas d'échec process.terminate() return False except Exception as e: print(f"❌ Erreur démarrage serveur: {e}") return False finally: # Nettoyer le script temporaire en cas d'échec if temp_script and temp_script.exists(): try: temp_script.unlink() except: pass def update_env_server_url(new_url): """Met à jour l'URL du serveur dans .env.local""" env_path = Path(".env.local") if not env_path.exists(): return with open(env_path, 'r') as f: lines = f.readlines() # Chercher et modifier la ligne RPA_SERVER_URL modified = False for i, line in enumerate(lines): if line.strip().startswith('RPA_SERVER_URL='): lines[i] = f"RPA_SERVER_URL={new_url}\\n" modified = True break # Ajouter la ligne si elle n'existe pas if not modified: lines.append(f"RPA_SERVER_URL={new_url}\\n") with open(env_path, 'w') as f: f.writelines(lines) print(f"✓ URL serveur mise à jour dans .env.local") def save_server_info(pid, port, temp_script): """Sauvegarde les informations du serveur pour pouvoir l'arrêter""" info = { "pid": pid, "port": port, "temp_script": str(temp_script), "started_at": time.strftime("%Y-%m-%d %H:%M:%S") } with open("dev_server_info.json", "w") as f: import json json.dump(info, f, indent=2) print("✓ Informations serveur sauvegardées dans dev_server_info.json") def main(): """Démarrage du serveur de développement""" print("🎯 === SERVEUR API DÉVELOPPEMENT ===") if not start_dev_server(): print("❌ Échec du démarrage du serveur") return False return True if __name__ == "__main__": success = main() exit(0 if success else 1)