Importar y Exportar

Exporte proyectos como archivos portátiles .mpz para respaldo o transferencia, e impórtelos en otros tenants. También administre las imágenes en miniatura de los proyectos.

Paquetes de Proyecto (.mpz)

El formato .mpz es un mindzie Package Zip que contiene:

  • Configuraciones y metadatos del proyecto
  • Todos los conjuntos de datos y sus configuraciones
  • Investigaciones y cuadernos
  • Paneles y dashboards
  • Archivos de almacenamiento blob (registros de eventos, adjuntos)

Exportar Proyecto

GET /api/{tenantId}/project/{projectId}/download

Exporta el proyecto como un archivo .mpz (mindzie Package Zip).

Parámetros de Ruta

Parámetro Tipo Requerido Descripción
tenantId GUID Identificador del tenant
projectId GUID Proyecto a exportar

Respuesta

Devuelve una descarga de archivo binario con:

  • Content-Type: application/octet-stream
  • Nombre de archivo: {projectName}.mpz

Casos de Uso

  • Respaldo: Crear respaldos periódicos de proyectos importantes
  • Migración: Mover proyectos entre tenants o instancias
  • Plantillas: Exportar un proyecto configurado como plantilla para nuevos análisis

Importar Proyecto

POST /api/{tenantId}/project/import

Importa un proyecto desde un archivo .mpz.

Parámetros de Ruta

Parámetro Tipo Requerido Descripción
tenantId GUID Tenant destino

Solicitud

  • Content-Type: multipart/form-data
  • Parámetro de archivo: file (el archivo .mpz)

Restricciones

Restricción Valor
Tamaño máximo de archivo 1 GB
Extensión de archivo Debe ser .mpz
Formato de archivo Debe ser una exportación válida de proyecto mindzie

Respuesta (200 OK)

{
  "success": true,
  "projectId": "99999999-9999-9999-9999-999999999999",
  "projectName": "Proyecto Importado",
  "datasetsImported": 2,
  "investigationsImported": 3,
  "dashboardsImported": 1,
  "message": "Proyecto importado exitosamente"
}

Campos de Respuesta

Campo Tipo Descripción
success boolean Si la importación fue exitosa
projectId GUID ID del proyecto recién creado
projectName string Nombre del proyecto importado
datasetsImported integer Número de conjuntos de datos importados
investigationsImported integer Número de investigaciones importadas
dashboardsImported integer Número de dashboards importados
message string Estado legible para humanos

Respuestas de Error

Solicitud Incorrecta (400):

{
  "success": false,
  "errorMessage": "Formato de archivo inválido. Se esperaba archivo .mpz."
}

Gestión de Miniaturas

Las miniaturas de proyecto se muestran en la lista de proyectos y proporcionan identificación visual.

Obtener Miniatura

GET /api/{tenantId}/project/{projectId}/thumbnail

Recupera la imagen miniatura del proyecto.

Respuesta (200 OK)

{
  "projectId": "87654321-4321-4321-4321-210987654321",
  "hasThumbnail": true,
  "base64Image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."
}

Campos de Respuesta

Campo Tipo Descripción
projectId GUID Identificador del proyecto
hasThumbnail boolean Si existe una miniatura
base64Image string Imagen codificada en base64 con prefijo URI de datos

Actualizar Miniatura

POST /api/{tenantId}/project/{projectId}/thumbnail

Actualiza la imagen miniatura del proyecto.

Cuerpo de Solicitud

{
  "base64Image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."
}

Nota: La cadena base64 debe incluir el prefijo URI de datos (por ejemplo, data:image/jpeg;base64, o data:image/png;base64,).

Respuesta (200 OK)

{
  "message": "Miniatura actualizada exitosamente"
}

Eliminar Miniatura

DELETE /api/{tenantId}/project/{projectId}/thumbnail

Elimina la imagen miniatura del proyecto.

Respuesta (200 OK)

{
  "message": "Miniatura eliminada exitosamente"
}

Ejemplos de Implementación

cURL

# Exportar proyecto a archivo
curl -X GET "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/87654321-4321-4321-4321-210987654321/download" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  --output project_backup.mpz

# Importar proyecto desde archivo
curl -X POST "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/import" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -F "file=@project_backup.mpz"

# Obtener miniatura
curl -X GET "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/87654321-4321-4321-4321-210987654321/thumbnail" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Actualizar miniatura (desde archivo base64)
curl -X POST "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/87654321-4321-4321-4321-210987654321/thumbnail" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"base64Image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."}'

# Eliminar miniatura
curl -X DELETE "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/project/87654321-4321-4321-4321-210987654321/thumbnail" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Python

import requests
import base64
from pathlib import Path

TENANT_ID = '12345678-1234-1234-1234-123456789012'
BASE_URL = 'https://your-mindzie-instance.com'

class ProjectExportManager:
    def __init__(self, token):
        self.headers = {
            'Authorization': f'Bearer {token}'
        }

    def export_project(self, project_id, output_path):
        """Exportar proyecto a archivo .mpz."""
        url = f'{BASE_URL}/api/{TENANT_ID}/project/{project_id}/download'
        response = requests.get(url, headers=self.headers, stream=True)
        response.raise_for_status()

        with open(output_path, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)

        print(f"Exportado a {output_path}")
        return output_path

    def import_project(self, file_path):
        """Importar proyecto desde archivo .mpz."""
        url = f'{BASE_URL}/api/{TENANT_ID}/project/import'

        with open(file_path, 'rb') as f:
            files = {'file': (Path(file_path).name, f, 'application/octet-stream')}
            response = requests.post(url, headers=self.headers, files=files)

        response.raise_for_status()
        result = response.json()

        print(f"Importado: {result['projectName']}")
        print(f"  Conjuntos de datos: {result['datasetsImported']}")
        print(f"  Investigaciones: {result['investigationsImported']}")
        print(f"  Dashboards: {result['dashboardsImported']}")

        return result

    def get_thumbnail(self, project_id):
        """Obtener miniatura del proyecto en base64."""
        url = f'{BASE_URL}/api/{TENANT_ID}/project/{project_id}/thumbnail'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def set_thumbnail(self, project_id, image_path):
        """Establecer miniatura del proyecto desde archivo de imagen."""
        url = f'{BASE_URL}/api/{TENANT_ID}/project/{project_id}/thumbnail'

        # Leer y codificar imagen
        with open(image_path, 'rb') as f:
            image_data = f.read()

        # Determinar tipo MIME
        ext = Path(image_path).suffix.lower()
        mime_type = 'image/jpeg' if ext in ['.jpg', '.jpeg'] else 'image/png'

        # Crear URI de datos base64
        base64_data = base64.b64encode(image_data).decode('utf-8')
        data_uri = f'data:{mime_type};base64,{base64_data}'

        headers = {**self.headers, 'Content-Type': 'application/json'}
        response = requests.post(url, json={'base64Image': data_uri}, headers=headers)
        response.raise_for_status()

        print(f"Miniatura actualizada para proyecto {project_id}")
        return response.json()

    def remove_thumbnail(self, project_id):
        """Eliminar miniatura del proyecto."""
        url = f'{BASE_URL}/api/{TENANT_ID}/project/{project_id}/thumbnail'
        response = requests.delete(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

# Uso
manager = ProjectExportManager('your-auth-token')
project_id = '87654321-4321-4321-4321-210987654321'

# Exportar proyecto para respaldo
manager.export_project(project_id, 'my_project_backup.mpz')

# Importar en mismo o diferente tenant
result = manager.import_project('my_project_backup.mpz')
new_project_id = result['projectId']

# Establecer una miniatura
manager.set_thumbnail(project_id, 'project_thumbnail.png')

# Obtener miniatura
thumbnail = manager.get_thumbnail(project_id)
if thumbnail['hasThumbnail']:
    print("La miniatura existe")

JavaScript/Node.js

const fs = require('fs');
const path = require('path');
const FormData = require('form-data');

const TENANT_ID = '12345678-1234-1234-1234-123456789012';
const BASE_URL = 'https://your-mindzie-instance.com';

class ProjectExportManager {
  constructor(token) {
    this.headers = {
      'Authorization': `Bearer ${token}`
    };
  }

  async exportProject(projectId, outputPath) {
    const url = `${BASE_URL}/api/${TENANT_ID}/project/${projectId}/download`;
    const response = await fetch(url, { headers: this.headers });

    if (!response.ok) {
      throw new Error(`Error en exportación: ${response.status}`);
    }

    const buffer = await response.arrayBuffer();
    fs.writeFileSync(outputPath, Buffer.from(buffer));
    console.log(`Exportado a ${outputPath}`);
  }

  async importProject(filePath) {
    const url = `${BASE_URL}/api/${TENANT_ID}/project/import`;

    const formData = new FormData();
    formData.append('file', fs.createReadStream(filePath));

    const response = await fetch(url, {
      method: 'POST',
      headers: {
        ...this.headers,
        ...formData.getHeaders()
      },
      body: formData
    });

    if (!response.ok) {
      throw new Error(`Error en importación: ${response.status}`);
    }

    const result = await response.json();
    console.log(`Importado: ${result.projectName}`);
    return result;
  }

  async setThumbnail(projectId, imagePath) {
    const url = `${BASE_URL}/api/${TENANT_ID}/project/${projectId}/thumbnail`;

    // Leer y codificar imagen
    const imageBuffer = fs.readFileSync(imagePath);
    const ext = path.extname(imagePath).toLowerCase();
    const mimeType = ext === '.png' ? 'image/png' : 'image/jpeg';
    const base64Data = imageBuffer.toString('base64');
    const dataUri = `data:${mimeType};base64,${base64Data}`;

    const response = await fetch(url, {
      method: 'POST',
      headers: {
        ...this.headers,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ base64Image: dataUri })
    });

    if (!response.ok) {
      throw new Error(`Error al actualizar miniatura: ${response.status}`);
    }

    return await response.json();
  }
}

// Uso
const manager = new ProjectExportManager('your-auth-token');

// Exportar e importar
await manager.exportProject('project-id', 'backup.mpz');
const imported = await manager.importProject('backup.mpz');

// Establecer miniatura
await manager.setThumbnail('project-id', 'thumbnail.png');

Mejores Prácticas

  1. Respaldos Regulares: Programe exportaciones regulares de proyectos importantes
  2. Nombrado de Versiones: Incluya fechas en los nombres de archivo de exportación (p.ej., project_2024-01-15.mpz)
  3. Pruebas de Importación: Pruebe las importaciones en un tenant no productivo antes de producción
  4. Tamaño de Miniatura: Mantenga las miniaturas por debajo de 100KB para carga rápida
  5. Formato de Miniatura: Use JPEG para fotos, PNG para gráficos con transparencia