SIDEL_ScriptsManager/PROXY-SYSTEM-README.md

336 lines
7.7 KiB
Markdown

# 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("""
<h1>Mi Script</h1>
<p>Workspace: {{ workspace }}</p>
<p>Parámetros: {{ parameters }}</p>
""", 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!** 🚀