Endpoint: GET /api/racks/visio/session/{id} — polling estado conversión
Descripción
Endpoint de polling que devuelve el estado actual de una conversión Visio asíncrona en curso. El frontend lo consulta cada 2.5 segundos tras lanzar POST /api/visio/analyze con un fichero .vsdx/.vsd.
Ruta: GET /api/racks/visio/session/{session_id}
Auth: Django user + Organization RLS
Content-Type: application/json
Contrato de respuesta
En progreso
{
"status": "processing",
"progress": 45,
"message": "Extracting shapes..."
}
Completado
{
"status": "done",
"masters": [
{
"name": "Switch 48-port",
"image_path": "preview_image.svg",
"u_height": 1,
"half_width": false
}
]
}
Error
{
"status": "error",
"error": "File corrupted or unsupported format"
}
Campos:
status—"processing","done", o"error".masters— (solo sistatus=done) Lista de shapes extraídos, como enanalyze_visio().progress— (opcional) Porcentaje estimado de progreso (0-100).message— (opcional) Mensaje amigable al usuario.error— (sistatus=error) Descripción del error.
Lógica de negocio
Almacenamiento de estado
El estado de la conversión se guarda en Redis cache con clave:
visio_session:{session_id}
Estructura en cache:
{
"organization_id": 123, # RLS check
"status": "processing|done|error",
"masters": [...],
"error": None,
"started_at": "2026-07-13T11:30:00Z",
"updated_at": "2026-07-13T11:30:15Z",
}
Flujo de vida de una sesión
POST /api/visio/analyze→ crea sesión constatus=processing, arranca Celery task.- Celery task corre → actualiza cache con progreso y masters a medida que extrae shapes.
- Frontend hace polling → lee cache, renderiza spinner si
processing, grid sidone. - Timeout de cache: 1 hora tras completarse — permite repolling.
- Limpieza: ficheros temp se limpian en background tras 4 horas.
Seguridad (RLS)
- Organization check: el endpoint valida que
session.organization_id == request.user.organization.id. - Sin exposición cross-org: si un usuario intenta consultar sesión de otra org, recibe 403.
- Session ID opaco: es un UUID aleatorio, no predecible.
Integración con Celery
El task convert_visio_async(session_id, filepath) actualiza la sesión:
@db_task
def convert_visio_async(session_id: str, filepath: str):
try:
# Actualiza estado
cache.set(f"visio_session:{session_id}", {"status": "processing", ...})
# Convierte
parser = VisioParser(filepath)
masters = parser.extract_masters(f"temp/{session_id}")
# Notifica completada
cache.set(f"visio_session:{session_id}", {
"status": "done",
"masters": masters,
}, timeout=3600)
except Exception as e:
cache.set(f"visio_session:{session_id}", {
"status": "error",
"error": str(e),
}, timeout=3600)
Frontend polling
async function pollVisioSession(sessionId) {
const started = Date.now();
while (Date.now() - started < 4 * 60 * 1000) { // 4 min timeout
await sleep(2500); // cada 2.5 segundos
const state = await ApiService.get(`/api/racks/visio/session/${sessionId}`);
if (state.status === 'done') return state.masters;
if (state.status === 'error') throw new Error(state.error);
}
throw new Error('Timeout');
}
Manejo de errores
| Código | Escenario |
|---|---|
| 200 | ✅ Sesión encontrada (cualquier estado). |
| 400 | Session ID mal formado. |
| 401 | No autenticado. |
| 403 | Organization RLS violation (sesión de otra org). |
| 404 | Sesión no encontrada (expiró, nunca existió). |
| 500 | Error al leer cache / DB. |
Performance
- Latencia típica: < 50 ms (lectura Redis).
- Overhead de polling: 2.5 segundos × ~60 segundos típicos = ~24 requests (aceptable).
- Max timeout: 4 minutos × 60s / 2.5s = ~96 requests máximo.
Cambios en v1.53.0
- Nuevo en v1.53.0 — introducido para soportar polling asincrónico en
.vsdx/.vsd. - Anterior (v1.52.0): solo formatos rápidos (
.vssx,.vdx,.vss) que se procesaban en-line.
Véase también
- [[feature—stencils—visio-v2-ui-preview]] — Feature completa (UI + API)
- [[entity—racks—endpoint—analyze-visio]] — Endpoint que inicia la conversión
- [[entity—racks—endpoint—confirm-visio-import]] — Endpoint que persiste los stencils