aef8791151
- Added Appshell component with responsive navbar and main content area - Integrated ColorSchemeToggle for light/dark mode switching - Created Welcome component with styled title and introductory text - Developed ChatPage for LLM interaction with WebSocket support - Implemented Biblioteca for managing notes with rich text editor - Added LoginPage for user authentication with error handling - Introduced MessageList and MessageBubble components for chat messages - Styled components with CSS modules for consistent design
48 lines
1.8 KiB
Python
48 lines
1.8 KiB
Python
# server_runner.py
|
|
import subprocess
|
|
import asyncio
|
|
import socket
|
|
import re
|
|
from pathlib import Path
|
|
|
|
async def wait_for_port(host: str, port: int, timeout: float = 10.0):
|
|
for _ in range(int(timeout * 10)):
|
|
try:
|
|
with socket.create_connection((host, port), timeout=0.5):
|
|
return True
|
|
except (OSError, ConnectionRefusedError):
|
|
await asyncio.sleep(0.1)
|
|
raise TimeoutError(f"No se pudo conectar al servidor en {host}:{port}")
|
|
|
|
class MCPServerRunner:
|
|
def __init__(self, server_script_path: str, python_path: str = "python"):
|
|
self.server_script_path = server_script_path
|
|
self.python_path = python_path
|
|
self.port: int = self._extraer_puerto()
|
|
self.process: subprocess.Popen | None = None
|
|
|
|
def _extraer_puerto(self) -> int:
|
|
contenido = Path(self.server_script_path).read_text(encoding="utf-8")
|
|
coincidencias = re.findall(r"port\s*=\s*(\d+)", contenido)
|
|
if not coincidencias:
|
|
raise ValueError(f"No se pudo detectar el puerto en {self.server_script_path}")
|
|
return int(coincidencias[0])
|
|
|
|
async def start(self):
|
|
if self.process is None or self.process.poll() is not None:
|
|
self.process = subprocess.Popen(
|
|
[self.python_path, self.server_script_path],
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE
|
|
)
|
|
await wait_for_port("127.0.0.1", self.port)
|
|
print(f"🟢 Servidor MCP iniciado en puerto {self.port}")
|
|
|
|
async def stop(self):
|
|
if self.process and self.process.poll() is None:
|
|
self.process.terminate()
|
|
try:
|
|
self.process.wait(timeout=5)
|
|
except subprocess.TimeoutExpired:
|
|
self.process.kill()
|
|
print("🔴 Servidor MCP detenido") |