Carnets Python

Intégration Jupyter Notebook

Intégrez des carnets Jupyter pour des enrichissements personnalisés, l'analyse des données et des workflows de machine learning.

Obtenir les Détails du Carnet

GET /api/{tenantId}/{projectId}/notebook/{notebookId}

Récupère des informations complètes sur un carnet Jupyter, y compris ses cellules, le statut d'exécution et les paramètres d'intégration.

Paramètres

Paramètre Type Emplacement Description
tenantId GUID Chemin L'identifiant du locataire
projectId GUID Chemin L'identifiant du projet
notebookId GUID Chemin L'identifiant du carnet

Réponse

{
  "notebookId": "aa0e8400-e29b-41d4-a716-446655440000",
  "projectId": "660e8400-e29b-41d4-a716-446655440000",
  "notebookName": "Process Mining Analysis",
  "notebookDescription": "Analyse personnalisée pour l'optimisation du parcours client",
  "notebookVersion": "1.3.2",
  "kernelType": "python3",
  "status": "Ready",
  "integration": {
    "enrichmentMode": true,
    "datasetBinding": "880e8400-e29b-41d4-a716-446655440000",
    "outputFormat": "enriched_dataframe",
    "autoExecution": false
  },
  "cells": [
    {
      "cellId": "cell-001",
      "cellType": "code",
      "executionCount": 15,
      "hasOutput": true,
      "lastExecuted": "2024-01-20T10:30:00Z",
      "executionStatus": "Success"
    },
    {
      "cellId": "cell-002",
      "cellType": "markdown",
      "lastModified": "2024-01-19T14:20:00Z"
    }
  ],
  "environment": {
    "pythonVersion": "3.9.18",
    "packages": ["pandas", "numpy", "scikit-learn", "mindzie-sdk"],
    "customLibraries": ["process_mining_utils", "customer_analytics"]
  },
  "dateCreated": "2024-01-15T10:30:00Z",
  "dateModified": "2024-01-20T10:30:00Z",
  "createdBy": "user123",
  "lastExecutionDate": "2024-01-20T10:30:00Z",
  "executionCount": 47
}

Lister Tous les Carnets

GET /api/{tenantId}/{projectId}/notebooks

Récupère la liste de tous les carnets Jupyter du projet avec les métadonnées de base et le statut d'exécution.

Paramètres de Requête

Paramètre Type Description
status string Filtrer par statut : Ready, Running, Error, Kernel_Dead
kernelType string Filtrer par type de noyau : python3, r, scala
enrichmentMode boolean Filtrer les carnets configurés pour l'enrichissement de données
page integer Numéro de page pour la pagination (par défaut : 1)
pageSize integer Nombre d'éléments par page (par défaut : 20, max : 100)

Réponse

{
  "notebooks": [
    {
      "notebookId": "aa0e8400-e29b-41d4-a716-446655440000",
      "notebookName": "Process Mining Analysis",
      "kernelType": "python3",
      "status": "Ready",
      "enrichmentMode": true,
      "cellCount": 12,
      "lastExecutionDate": "2024-01-20T10:30:00Z",
      "dateCreated": "2024-01-15T10:30:00Z"
    }
  ],
  "totalCount": 8,
  "page": 1,
  "pageSize": 20,
  "hasNextPage": false
}

Créer un Nouveau Carnet

POST /api/{tenantId}/{projectId}/notebook

Crée un nouveau carnet Jupyter avec la configuration spécifiée et un modèle optionnel. Le carnet est automatiquement configuré pour l'intégration des données mindzie.

Corps de la Requête

{
  "notebookName": "Advanced Customer Analytics",
  "notebookDescription": "Modèles de machine learning pour la prédiction du comportement client",
  "kernelType": "python3",
  "template": "process_mining_starter",
  "integration": {
    "enrichmentMode": true,
    "datasetBinding": "880e8400-e29b-41d4-a716-446655440000",
    "outputFormat": "enriched_dataframe",
    "autoExecution": false
  },
  "environment": {
    "packages": ["pandas", "numpy", "scikit-learn", "matplotlib", "seaborn"],
    "customLibraries": ["process_mining_utils"]
  },
  "initialCells": [
    {
      "cellType": "markdown",
      "content": "# Customer Analytics Notebook\n\nCe carnet analyse les données du parcours client à l'aide des techniques de process mining."
    },
    {
      "cellType": "code",
      "content": "import pandas as pd\nimport numpy as np\nfrom mindzie_sdk import ProcessMiningClient\n\n# Initialiser le client mindzie\nclient = ProcessMiningClient()"
    }
  ]
}

Réponse

Retourne 201 Created avec l'objet complet du carnet incluant l'ID généré et les informations initiales de session.

Exécuter un Carnet

POST /api/{tenantId}/{projectId}/notebook/{notebookId}/execute

Exécute toutes les cellules du carnet ou la plage de cellules spécifiée. L'exécution est asynchrone et les résultats sont stockés pour récupération.

Corps de la Requête

{
  "executionMode": "all",
  "cellRange": {
    "startCell": "cell-001",
    "endCell": "cell-010"
  },
  "parameters": {
    "dataset_id": "880e8400-e29b-41d4-a716-446655440000",
    "analysis_period": "2024-01",
    "include_weekends": false
  },
  "outputOptions": {
    "captureOutputs": true,
    "saveIntermediateResults": true,
    "generateReport": true
  },
  "timeout": 1800,
  "priority": "Normal"
}

Réponse

{
  "executionId": "bb0e8400-e29b-41d4-a716-446655440000",
  "notebookId": "aa0e8400-e29b-41d4-a716-446655440000",
  "status": "Running",
  "startTime": "2024-01-20T10:30:00Z",
  "estimatedDuration": "15-20 minutes",
  "currentCell": "cell-003",
  "progress": {
    "totalCells": 12,
    "completedCells": 2,
    "currentCellIndex": 3,
    "percentComplete": 17
  },
  "parameters": {
    "dataset_id": "880e8400-e29b-41d4-a716-446655440000",
    "analysis_period": "2024-01",
    "include_weekends": false
  }
}

Obtenir le Statut d'Exécution

GET /api/{tenantId}/{projectId}/notebook/{notebookId}/execution/{executionId}

Récupère le statut actuel et la progression d'une exécution de carnet, incluant les détails d'exécution cellule par cellule et les éventuelles erreurs.

Réponse

{
  "executionId": "bb0e8400-e29b-41d4-a716-446655440000",
  "notebookId": "aa0e8400-e29b-41d4-a716-446655440000",
  "status": "Completed",
  "startTime": "2024-01-20T10:30:00Z",
  "endTime": "2024-01-20T10:47:00Z",
  "totalDuration": "17 minutes",
  "progress": {
    "totalCells": 12,
    "completedCells": 12,
    "successfulCells": 11,
    "failedCells": 1,
    "percentComplete": 100
  },
  "cellResults": [
    {
      "cellId": "cell-001",
      "status": "Success",
      "executionTime": "0.5 seconds",
      "hasOutput": false
    },
    {
      "cellId": "cell-002",
      "status": "Success",
      "executionTime": "3.2 seconds",
      "hasOutput": true,
      "outputType": "display_data"
    },
    {
      "cellId": "cell-003",
      "status": "Error",
      "executionTime": "1.1 seconds",
      "errorType": "KeyError",
      "errorMessage": "Colonne 'customer_id' introuvable dans le dataset"
    }
  ],
  "outputs": {
    "dataFrames": 3,
    "plots": 5,
    "models": 2,
    "enrichedData": {
      "recordCount": 15420,
      "newColumns": ["customer_segment", "journey_score", "anomaly_flag"]
    }
  },
  "resources": {
    "peakMemoryUsage": "2.3 GB",
    "cpuTime": "8.5 minutes",
    "diskUsage": "450 MB"
  }
}

Obtenir les Résultats d'Exécution

GET /api/{tenantId}/{projectId}/notebook/{notebookId}/execution/{executionId}/results

Récupère les sorties et résultats d'une exécution de carnet terminée, incluant les données générées, graphiques et datasets enrichis.

Paramètres de Requête

Paramètre Type Description
outputType string Filtrer par type de sortie : all, data, plots, models, reports
format string Format de la réponse : summary, detailed, download
cellId string Obtenir les résultats d'une cellule spécifique uniquement

Réponse

{
  "executionId": "bb0e8400-e29b-41d4-a716-446655440000",
  "status": "Completed",
  "outputs": [
    {
      "cellId": "cell-002",
      "outputType": "display_data",
      "contentType": "text/html",
      "title": "Aperçu du Dataset",
      "content": "<div>Le dataset contient 15 420 enregistrements...</div>",
      "downloadUrl": "https://api.mindzie.com/downloads/cell-002-bb0e8400.html"
    },
    {
      "cellId": "cell-005",
      "outputType": "image/png",
      "title": "Diagramme du Parcours Client",
      "dimensions": {"width": 800, "height": 600},
      "downloadUrl": "https://api.mindzie.com/downloads/cell-005-bb0e8400.png"
    },
    {
      "cellId": "cell-008",
      "outputType": "application/json",
      "title": "Métriques de Process Mining",
      "content": {
        "avgCycleTime": "4.2 heures",
        "bottleneckActivities": ["Révision de la candidature", "Approbation du manager"],
        "processEfficiency": 78.5,
        "customerSatisfactionScore": 8.2
      },
      "downloadUrl": "https://api.mindzie.com/downloads/cell-008-bb0e8400.json"
    }
  ],
  "enrichedDatasets": [
    {
      "name": "customer_journey_enhanced",
      "recordCount": 15420,
      "newColumns": ["customer_segment", "journey_score", "anomaly_flag"],
      "format": "pandas_dataframe",
      "downloadUrl": "https://api.mindzie.com/downloads/enriched-bb0e8400.csv"
    }
  ],
  "models": [
    {
      "name": "customer_churn_predictor",
      "modelType": "RandomForestClassifier",
      "accuracy": 0.87,
      "features": ["journey_score", "cycle_time", "touchpoint_count"],
      "downloadUrl": "https://api.mindzie.com/downloads/model-bb0e8400.pkl"
    }
  ],
  "reports": [
    {
      "name": "Résumé Analytics Client",
      "format": "html",
      "downloadUrl": "https://api.mindzie.com/downloads/report-bb0e8400.html"
    }
  ]
}

Mettre à Jour un Carnet

PUT /api/{tenantId}/{projectId}/notebook/{notebookId}

Met à jour la configuration du carnet, les cellules ou les paramètres d'intégration. Les modifications des cellules déclencheront une nouvelle version du carnet.

Corps de la Requête

{
  "notebookName": "Advanced Customer Analytics v2",
  "notebookDescription": "Modèles ML améliorés avec capacités de prédiction en temps réel",
  "integration": {
    "enrichmentMode": true,
    "datasetBinding": "880e8400-e29b-41d4-a716-446655440000",
    "outputFormat": "enriched_dataframe",
    "autoExecution": true,
    "scheduleExecution": "0 2 * * *"
  },
  "environment": {
    "packages": ["pandas", "numpy", "scikit-learn", "tensorflow", "matplotlib"],
    "customLibraries": ["process_mining_utils", "ml_models"]
  }
}

Réponse

Retourne l'objet carnet mis à jour avec un numéro de version incrémenté et les horodatages de modification.

Supprimer un Carnet

DELETE /api/{tenantId}/{projectId}/notebook/{notebookId}

Supprime définitivement un carnet et tout son historique d'exécution. Cette opération est irréversible et arrêtera toute exécution en cours.

Codes de Réponse

  • 204 No Content - Carnet supprimé avec succès
  • 404 Not Found - Carnet non trouvé ou accès refusé
  • 409 Conflict - Carnet en cours d'exécution et ne peut pas être supprimé

Importer un Carnet Existants

POST /api/{tenantId}/{projectId}/notebook/upload

Importe un carnet Jupyter existant (fichier .ipynb) et le configure pour l'intégration mindzie. Le carnet est analysé et les cellules validées.

Requête (Données Multipart Form)

Content-Type: multipart/form-data

--boundary
Content-Disposition: form-data; name="file"; filename="analysis.ipynb"
Content-Type: application/json

{notebook content}
--boundary
Content-Disposition: form-data; name="notebookName"

Analyse du Parcours Client
--boundary
Content-Disposition: form-data; name="enrichmentMode"

true
--boundary
Content-Disposition: form-data; name="datasetBinding"

880e8400-e29b-41d4-a716-446655440000
--boundary--

Réponse

Retourne 201 Created avec l'objet carnet importé incluant les résultats d'analyse et les avertissements de validation éventuels.

Exemple : Workflow Complet d'un Carnet

Cet exemple montre la création, l'exécution et la récupération des résultats d'un carnet Jupyter :

// 1. Créer un nouveau carnet
const createNotebook = async () => {
  const response = await fetch('/api/{tenantId}/{projectId}/notebook', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      notebookName: 'Process Mining Analysis',
      notebookDescription: 'Analyse avancée pour l’optimisation des processus',
      kernelType: 'python3',
      template: 'process_mining_starter',
      integration: {
        enrichmentMode: true,
        datasetBinding: '880e8400-e29b-41d4-a716-446655440000',
        outputFormat: 'enriched_dataframe',
        autoExecution: false
      },
      environment: {
        packages: ['pandas', 'numpy', 'scikit-learn', 'matplotlib'],
        customLibraries: ['process_mining_utils']
      },
      initialCells: [
        {
          cellType: 'markdown',
          content: '# Analyse Process Mining\n\nAnalyse de l’efficacité des processus et des goulets d’étranglement.'
        },
        {
          cellType: 'code',
          content: 'import pandas as pd\nfrom mindzie_sdk import ProcessMiningClient\n\nclient = ProcessMiningClient()'
        }
      ]
    })
  });

  return await response.json();
};

// 2. Exécuter le carnet
const executeNotebook = async (notebookId) => {
  const response = await fetch(`/api/{tenantId}/{projectId}/notebook/${notebookId}/execute`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      executionMode: 'all',
      parameters: {
        dataset_id: '880e8400-e29b-41d4-a716-446655440000',
        analysis_period: '2024-01',
        include_weekends: false
      },
      outputOptions: {
        captureOutputs: true,
        saveIntermediateResults: true,
        generateReport: true
      },
      timeout: 1800,
      priority: 'High'
    })
  });

  return await response.json();
};

// 3. Suivre la progression de l'exécution
const monitorNotebookExecution = async (notebookId, executionId) => {
  const checkStatus = async () => {
    const response = await fetch(`/api/{tenantId}/{projectId}/notebook/${notebookId}/execution/${executionId}`, {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    const execution = await response.json();
    console.log(`Statut : ${execution.status}, Progression : ${execution.progress.percentComplete}%`);

    if (execution.status === 'Running') {
      setTimeout(() => checkStatus(), 15000);
    } else if (execution.status === 'Completed') {
      console.log('Exécution du carnet terminée !');
      await getNotebookResults(notebookId, executionId);
    } else if (execution.status === 'Error') {
      console.log('Exécution échouée :', execution.cellResults.filter(c => c.status === 'Error'));
    }
  };

  await checkStatus();
};

// 4. Obtenir les résultats d'exécution
const getNotebookResults = async (notebookId, executionId) => {
  const response = await fetch(`/api/{tenantId}/{projectId}/notebook/${notebookId}/execution/${executionId}/results?format=detailed`, {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  const results = await response.json();
  console.log('Résultats d’exécution :', results);
  console.log('Datasets enrichis :', results.enrichedDatasets);
  console.log('Modèles générés :', results.models);

  return results;
};

// Exécuter le workflow
createNotebook()
  .then(notebook => {
    console.log(`Carnet créé : ${notebook.notebookId}`);
    return executeNotebook(notebook.notebookId);
  })
  .then(execution => {
    console.log(`Exécution lancée : ${execution.executionId}`);
    return monitorNotebookExecution(execution.notebookId, execution.executionId);
  })
  .catch(error => console.error('Échec du workflow carnet :', error));

Exemple Python

import requests
import time
import json
from pathlib import Path

class NotebookManager:
    def __init__(self, base_url, tenant_id, project_id, token):
        self.base_url = base_url
        self.tenant_id = tenant_id
        self.project_id = project_id
        self.headers = {
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }

    def create_notebook(self, name, description, kernel_type="python3", template=None, integration=None):
        """Créer un nouveau carnet Jupyter"""
        url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/notebook"
        payload = {
            'notebookName': name,
            'notebookDescription': description,
            'kernelType': kernel_type,
            'template': template,
            'integration': integration or {
                'enrichmentMode': True,
                'outputFormat': 'enriched_dataframe',
                'autoExecution': False
            }
        }
        response = requests.post(url, json=payload, headers=self.headers)
        return response.json()

    def upload_notebook(self, file_path, name, dataset_binding=None):
        """Importer un fichier carnet existant"""
        url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/notebook/upload"

        with open(file_path, 'rb') as file:
            files = {'file': (Path(file_path).name, file, 'application/json')}
            data = {
                'notebookName': name,
                'enrichmentMode': 'true',
                'datasetBinding': dataset_binding or ''
            }
            # Retirer l'en-tête Content-Type pour l'upload multipart
            headers = {k: v for k, v in self.headers.items() if k != 'Content-Type'}
            response = requests.post(url, files=files, data=data, headers=headers)

        return response.json()

    def execute_notebook(self, notebook_id, parameters=None, timeout=1800):
        """Exécuter toutes les cellules d’un carnet"""
        url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/notebook/{notebook_id}/execute"
        payload = {
            'executionMode': 'all',
            'parameters': parameters or {},
            'outputOptions': {
                'captureOutputs': True,
                'saveIntermediateResults': True,
                'generateReport': True
            },
            'timeout': timeout,
            'priority': 'Normal'
        }
        response = requests.post(url, json=payload, headers=self.headers)
        return response.json()

    def get_execution_status(self, notebook_id, execution_id):
        """Obtenir le statut d'exécution du carnet"""
        url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/notebook/{notebook_id}/execution/{execution_id}"
        response = requests.get(url, headers=self.headers)
        return response.json()

    def wait_for_completion(self, notebook_id, execution_id, poll_interval=15, timeout=3600):
        """Attendre la fin d'exécution du carnet"""
        start_time = time.time()

        while time.time() - start_time < timeout:
            status = self.get_execution_status(notebook_id, execution_id)
            print(f"Carnet {notebook_id} : {status['status']} ({status['progress']['percentComplete']}%)")

            if status['status'] in ['Completed', 'Error', 'Cancelled']:
                return status

            time.sleep(poll_interval)

        raise TimeoutError(f"L’exécution du carnet {execution_id} n’a pas terminé dans les {timeout} secondes")

    def get_execution_results(self, notebook_id, execution_id, output_type="all", format_type="detailed"):
        """Obtenir les résultats d'exécution du carnet"""
        url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/notebook/{notebook_id}/execution/{execution_id}/results"
        params = {
            'outputType': output_type,
            'format': format_type
        }
        response = requests.get(url, params=params, headers=self.headers)
        return response.json()

    def list_notebooks(self, status=None, enrichment_mode=None, page=1, page_size=20):
        """Lister tous les carnets avec filtres optionnels"""
        url = f"{self.base_url}/api/{self.tenant_id}/{self.project_id}/notebooks"
        params = {'page': page, 'pageSize': page_size}

        if status:
            params['status'] = status
        if enrichment_mode is not None:
            params['enrichmentMode'] = str(enrichment_mode).lower()

        response = requests.get(url, params=params, headers=self.headers)
        return response.json()

# Exemple d'utilisation
manager = NotebookManager(
    'https://your-mindzie-instance.com',
    'tenant-guid',
    'project-guid',
    'your-auth-token'
)

try:
    # Créer un carnet de process mining
    notebook = manager.create_notebook(
        'Advanced Process Analytics',
        'Analyse de processus basée sur le machine learning avec détection d’anomalies',
        'python3',
        'process_mining_starter',
        {
            'enrichmentMode': True,
            'datasetBinding': 'dataset-guid',
            'outputFormat': 'enriched_dataframe',
            'autoExecution': False
        }
    )

    print(f"Carnet créé : {notebook['notebookId']}")

    # Exécuter avec des paramètres personnalisés
    execution_params = {
        'dataset_id': 'dataset-guid',
        'analysis_type': 'full_analysis',
        'time_window': '30_days',
        'ml_models': ['anomaly_detection', 'process_prediction'],
        'generate_visualizations': True
    }

    execution = manager.execute_notebook(
        notebook['notebookId'],
        execution_params,
        timeout=2400  # 40 minutes
    )

    print(f"Exécution lancée : {execution['executionId']}")
    print(f"Durée estimée : {execution['estimatedDuration']}")

    # Attendre la fin d'exécution
    final_status = manager.wait_for_completion(
        notebook['notebookId'],
        execution['executionId']
    )

    if final_status['status'] == 'Completed':
        # Obtenir les résultats détaillés
        results = manager.get_execution_results(
            notebook['notebookId'],
            execution['executionId'],
            'all',
            'detailed'
        )

        print("Exécution du carnet terminée avec succès !")
        print(f"Sorties générées : {len(results['outputs'])}")
        print(f"Datasets enrichis : {len(results['enrichedDatasets'])}")
        print(f"Modèles ML créés : {len(results['models'])}")

        # Télécharger les données enrichies
        for dataset in results['enrichedDatasets']:
            print(f"Télécharger les données enrichies : {dataset['downloadUrl']}")

        # Télécharger les modèles
        for model in results['models']:
            print(f"Télécharger le modèle '{model['name']}': {model['downloadUrl']}")

    else:
        print(f"L'exécution du carnet a échoué avec le statut : {final_status['status']}")
        failed_cells = [cell for cell in final_status['cellResults'] if cell['status'] == 'Error']
        for cell in failed_cells:
            print(f"Échec de la cellule {cell['cellId']} : {cell['errorMessage']}")

except Exception as e:
    print(f"Erreur dans le workflow du carnet : {e}")