# ScriptsManager - Sistema de Proxy Interno ## 🚀 Nueva Arquitectura Implementada El ScriptsManager ahora incluye un **sistema de proxy interno** que permite ejecutar scripts Flask de forma más elegante y escalable. ### ✨ Características Principales - **Un solo puerto expuesto** (5002/5003) para toda la aplicación - **Puertos internos gestionados automáticamente** (5200-5400) - **Soporte para múltiples proyectos por usuario** - **Aislamiento completo** entre ejecuciones de diferentes usuarios - **Limpieza automática** de procesos inactivos - **Monitoreo en tiempo real** del estado de los scripts ## 🏗️ Arquitectura ``` Usuario External → ScriptsManager (puerto 5002/5003) ↓ /project/{project_id}/script/{script_id}/user/{user_id}/* ↓ http://localhost:{puerto_interno}/* ``` ### Flujo de Ejecución 1. **Usuario solicita ejecutar un script** a través de la interfaz web 2. **ScriptsManager asigna un puerto interno** (ej: 5234) 3. **Script se ejecuta como Flask app** en ese puerto interno 4. **Proxy redirige peticiones** de la URL pública al puerto interno 5. **Usuario accede al script** a través de URL amigable ## 📁 Estructura de URLs ### URLs de Acceso a Scripts ```bash # Página principal del script /project/{project_id}/script/{script_id}/user/{user_id}/ # Cualquier ruta del script /project/{project_id}/script/{script_id}/user/{user_id}/dashboard /project/{project_id}/script/{script_id}/user/{user_id}/api/data /project/{project_id}/script/{script_id}/user/{user_id}/results ``` ### URLs de Control ```bash # Iniciar script POST /project/{project_id}/script/{script_id}/user/{user_id}/_control/start # Detener script POST /project/{project_id}/script/{script_id}/user/{user_id}/_control/stop # Estado del script GET /project/{project_id}/script/{script_id}/user/{user_id}/_control/status ``` ### URLs Administrativas ```bash # Estadísticas del proxy (solo admin) GET /project/_admin/stats ``` ## 💻 Desarrollo de Scripts ### Estructura de Script Flask Los scripts ahora deben seguir esta estructura: ```python """ Mi Script Flask para ScriptsManager """ # Variables automáticas disponibles: # - WORKSPACE_PATH: directorio de trabajo del script # - PARAMETERS: parámetros pasados al script # - ENVIRONMENT: variables de entorno # - app: instancia Flask configurada from flask import render_template, request, jsonify import os @app.route('/') def index(): """Página principal del script""" return render_template_string("""

Mi Script

Workspace: {{ workspace }}

Parámetros: {{ parameters }}

""", workspace=WORKSPACE_PATH, parameters=PARAMETERS) @app.route('/api/data') def get_data(): """API endpoint del script""" return jsonify({ 'status': 'ok', 'data': 'Mi data personalizada' }) @app.route('/process', methods=['POST']) def process_data(): """Procesar datos""" data = request.get_json() # Procesar... return jsonify({'result': 'processed'}) ``` ### Variables Disponibles Cada script tiene acceso a: - `WORKSPACE_PATH`: Directorio de trabajo aislado - `PARAMETERS`: Diccionario con parámetros del usuario - `ENVIRONMENT`: Variables de entorno (USER_LEVEL, PROJECT_NAME, etc.) - `app`: Instancia Flask pre-configurada - `PROJECT_WORKSPACE`: Alias para WORKSPACE_PATH ### Health Check Automático Cada script **debe responder** en `/health`: ```python @app.route('/health') def health_check(): return {'status': 'ok', 'workspace': WORKSPACE_PATH}, 200 ``` ## 🔧 Uso desde Python ### Ejecutar Script con Proxy ```python from app.services.script_executor import ScriptExecutor executor = ScriptExecutor() # Ejecutar script usando el nuevo sistema de proxy result = executor.execute_script_with_proxy( script_id=1, user_id=1, project_id=1, parameters={'sample_size': 1000, 'mode': 'advanced'}, environment={'DEBUG': 'true'} ) if result['success']: print(f"Script disponible en: {result['proxy_url']}") print(f"Puerto interno: {result['internal_port']}") else: print(f"Error: {result['error']}") ``` ### Control de Scripts ```python # Detener script stop_result = executor.stop_script_proxy( script_id=1, user_id=1, project_id=1 ) # Obtener estado status = executor.get_script_proxy_status( script_id=1, user_id=1, project_id=1 ) ``` ## 🌐 APIs REST ### Iniciar Script ```bash curl -X POST http://localhost:5003/project/1/script/1/user/1/_control/start \ -H "Content-Type: application/json" \ -d '{"parameters": {"mode": "test"}, "environment": {"DEBUG": "true"}}' ``` **Respuesta:** ```json { "success": true, "proxy_url": "/project/1/script/1/user/1/", "internal_port": 5234, "message": "Script iniciado correctamente", "script_key": "1_1_1" } ``` ### Estado del Script ```bash curl http://localhost:5003/project/1/script/1/user/1/_control/status ``` **Respuesta:** ```json { "script_key": "1_1_1", "running": true, "proxy_service_info": { "status": "running", "port": 5234, "started_at": "2025-09-13T10:30:00", "last_activity": "2025-09-13T10:35:00" }, "database_info": { "id": 42, "status": "running", "workspace_path": "/app/workspaces/user_1/project_1/script_1" } } ``` ## 📊 Monitoreo y Administración ### Estadísticas del Proxy ```bash curl http://localhost:5003/project/_admin/stats ``` **Respuesta:** ```json { "total_scripts": 3, "used_ports": 3, "available_ports": 197, "port_range": "5200-5400", "scripts_by_status": { "running": 2, "starting": 1, "stopping": 0, "error": 0 } } ``` ## 🗄️ Base de Datos ### Nuevas Tablas #### `script_proxy_executions` - Registra scripts ejecutándose en el proxy - Relaciona project_id, script_id, user_id con puertos internos - Tracking de actividad y estado #### `execution_logs` (actualizada) - Nuevas columnas: `project_id`, `proxy_port`, `proxy_url`, `execution_mode` - Soporte para logging de ejecuciones proxy ### Migración Para aplicar los cambios de base de datos: ```bash python scripts/migrate_proxy_system.py ``` ## 🚦 Testing ### Script de Prueba Automático ```bash ./test_proxy_system.sh ``` Este script prueba: - Inicio de scripts - Proxy de peticiones - APIs internas - Detención de scripts - Estadísticas del sistema ### Script de Ejemplo Incluido en `data/script_groups/examples/example_flask_app.py`: - Interfaz web completa - Generación de datos - Creación de gráficos - Explorador de archivos - APIs REST ## 🔄 Migración desde Sistema Anterior ### Para Desarrolladores 1. **Scripts existentes**: Mantienen compatibilidad 2. **Nuevos scripts**: Usar formato Flask con variables automáticas 3. **APIs**: Cambiar de puertos directos a URLs proxy ### Beneficios del Nuevo Sistema - ✅ **Seguridad**: No más puertos expuestos - ✅ **Escalabilidad**: Pool de puertos gestionado - ✅ **Aislamiento**: Workspaces separados por proyecto/usuario - ✅ **Monitoreo**: Estado en tiempo real - ✅ **Limpieza**: Procesos inactivos eliminados automáticamente - ✅ **URLs amigables**: Rutas semánticas y organizadas ## 🛠️ Configuración ### Variables de Entorno ```bash # Rango de puertos internos PORT_RANGE_START=5200 PORT_RANGE_END=5400 # Timeout de inactividad (segundos) SCRIPT_TIMEOUT=3600 # Intervalo de limpieza (segundos) CLEANUP_INTERVAL=300 ``` ### Docker Compose Los nuevos volúmenes incluidos: ```yaml volumes: - ./workspaces:/app/workspaces # Workspaces aislados ``` ## 🎯 Próximos Pasos - [ ] Dashboard de monitoreo en tiempo real - [ ] WebSocket para logs en vivo - [ ] Límites de recursos por script - [ ] Backup automático de workspaces - [ ] Métricas de performance --- **¡El nuevo sistema de proxy está listo para usar!** 🚀