Volver a la wiki

Endpoint GET /api/racks/backup/full/download/{job_id} — Descargar ZIP (v1.56.0)

Signature

@router.get("/backup/full/download/{job_id}")
def backup_full_download(request, job_id: str):
    """GET /api/racks/backup/full/download/{job_id} - Descarga el ZIP de un backup async listo."""

Método: GET
Path: /api/racks/backup/full/download/{job_id}
Permisos: racks.admin
Respuesta: 200 OK (ZIP file, streaming) | 404 (no listo / no existe)

Descripción

Descarga el ZIP del backup completado, aislado por organización (RLS + ORM). El ZIP se auto-limpia tras servirse (POSIX unlink).

Response (200)

Content-Type: application/zip
Content-Disposition: attachment; filename="crearack_backup_ORGNAME_20260716_110418.zip"

[ZIP binary stream, ~50-500 MB típico]

Response (404)

{
  "error": "Backup not ready"  // o "Backup file expired"
}

Lógica interna

  1. Valida require_perm(request, "racks", "admin").
  2. Obtiene org = get_current_org(request).
  3. Query aislada por org + RLS:
    job = AsyncJob.objects.filter(
        job_id=job_id,
        organization=org,
        kind=AsyncJob.Kind.BACKUP_FULL
    ).first()
  4. Verifica:
    • Job existe y es de esta org.
    • Job está en status "done".
    • Archivo ZIP existe en ASYNC_BACKUP_DIR.
  5. Sirve el ZIP con FileResponse (streaming).
  6. Auto-limpia con os.unlink(zip_path) inmediato (en POSIX, la inode se mantiene viva mientras el filehandle de FileResponse esté abierto).

Seguridad

Multi-tenancy

Almacenamiento

Contenido

Consideraciones

Véase también

Subir