Découverte du Datalab

TP3 - Onyxia et le Datalab pour le statisticien
Author

Ludovic Deneuville

Introduction

Le Datalab permet aux statisticiens de découvrir, d’expérimenter, d’apprendre, de se former aux outils de la data.

Pourquoi un Datalab ?

Dans le monde professionnel, plusieurs problèmes se posent au statisticien :

  • sa machine n’est pas assez puissante
  • installer certains logiciels est parfois interdit et bloqué par le système
  • il doit analyser des données sensibles en toute sécurité

À l’INSEE, un projet est né pour pallier à ce besoin : Onyxia porté par le lab de l’INSEE.

La première étape fut de créer une infrastructure Cloud avec des CPUs, des GPUs, de la RAM et du stockage.

Ensuite, avoir plein de ressources c’est très bien, mais encore faut-il savoir les utiliser. Or lancer des services dans le cloud nécessite quelques compétences spécifiques (Docker, Kubernetes, Helm, S3…) qui ne sont pas à la portée de tous.

D’où l’idée de créer une interface graphique pour pouvoir lancer des services en quelques clics. Onyxia s’appuie sur des technologies sous-jacentes (Kubernetes, Helm, S3…) pour proposer une IHM agréable pour le datascientist. Cependant, la philosophie du projet Onyxia est d’être une brique qui facilite le travail sans se rendre indispensable. L’idée est d’éviter que les utilisateurs ne s’enferment dans un choix technologique et qu’il soit couteux d’en sortir.

À l’INSEE, une instance de ce logiciel a été installée sur le Datalab SSP Cloud, ouverte à tous les agents publics. Vous pouvez y créer un compte car c’est également ouvert à tous les élèves de l’ENSAI (en utilisant votre mail ENSAI).

Warning

Ne déposez pas de données sensibles sur cette instance, ni sur celle du GENES.

Pour celles et ceux qui iront à l’INSEE, une autre instance nommée LS3 n’est accessible qu’en interne et autorise l’utilisation de données sensibles.

Onyxia est un logiciel Libre et Open Source. Chacun peut installer sa propre instance sur son infra. C’est ce qu’ont fait de nombreux organismes, ainsi que le GENES.

Les services

Le principe est d’offrir aux utilisateurs la possibilité de lancer de nombreux services à la demande (Jupyter, Rstudio, VSCode, PostgreSQL…) avec une puissance de calcul adaptée aux besoins.

Caution

Ces services sont éphémères, car si les ressources sont importantes, il faut savoir les partager !

Le principe général est le suivant :

  • Vous lancez votre service en réservant des ressources (CPU, GPU, RAM, Stockage)
  • Vous effectuez votre travail
  • Vous sauvegardez votre code (git) et vos résultats (MinIO)
  • Vous supprimez votre service et libérez les ressources

Objectifs

Ce TP d’initiation va vous permettre de :

  • Lancer vos premiers services
  • Vous familiariser avec l’espace de stockage S3
  • Configurer votre compte sur le datalab
Fil rouge

Vos collègues Josette et Félix attendent un heureux événement. Ils avaient trouvé le prénom idéal pour leur enfant à naître.

Cependant, un malencontreux accident de fer à repasser les a rendu amnésiques tous les deux.

Votre mission, si vous l’acceptez, est de retrouver ce fameux prénom. Pour cela, vous allez devoir explorer les fonctionnalités du Datalab.

1 Se connecter

Vous pouvez réaliser ce TP soit sur :

2 Lancer un service

Fil rouge

Avant de partir à la recherche du prénom, Josette a une envie de doubitchou.

Vous retrouvez la recette, mais il vous manque la quantité exacte en grammes de margarine.

Vous savez simplement que la valeur recherchée correspond à combien il y a de nombres premiers entre 10 000 et 100 000.

Naturellement, vous vous dites que la solution la plus simple est de créer un programme Python pour trouver la réponse. Or, Python n’est pas installé sur votre machine et vous ne savez pas comment faire… Mais alors : pourquoi ne pas lancer un service du Datalab qui permet d’exécuter du Python.

2.1 Un premier service

Attendez quelques secondes le temps que le service se lance.

    • password : collez le mot de passe

Votre service Jupyter Python s’ouvre.

Pour plus de détails, vous pouvez consulter la vidéo en bas de la page.

Prenons l’exemple de ce qu’il se passe en arrière plan lorsque vous lancez un service Vscode-python :

Construction de l’image Docker

Une image Docker est un paquet léger et autonome qui contient tout le nécessaire pour exécuter une application : le code, les bibliothèques, les dépendances, les variables d’environnement et les fichiers de configuration.

Les images Docker permettent de créer des environnements isolés et cohérents, garantissant ainsi la portabilité et la reproductibilité des applications.

  1. Nous partons de l’image de base d’Onyxia
    • ubuntu:22.04 et quelques éléments de config
  2. Nous ajoutons la couche python-minimal
    • installation de python et quelques packages classiques
  3. Nous ajoutons la couche python-datascience
    • Julia, Quarto et des packages de datascience (numpy, pandas…)
  4. Nous ajoutons la couche vscode
    • Installation de Visual Studio Code et configuration

Vous avez maintenant une image Docker avec tout ce qu’il faut pour bien travailler.

DockerHub

Cette image est construite et déposée sur DockerHub onyxia-vscode-python.

Nous allons ensuite lancer une instance de cette image : un conteneur.

Une image est comme un moule, et un conteneur est un objet fabriqué à partir de ce moule. L’image contient les instructions, et le conteneur est l’instance concrète créée à partir de ce modèle. Vous verrez le même principe dans le cours de POO avec les classes (modèles) et les objets (instances)

Pour gérer tous les conteneurs lancés sur le datalab, nous avons besoin d’un orchestrateur : Kubernetes.

Chart Helm

Cependant, nous allons d’abord utiliser Helm pour faciliter le déploiement.

Helm simplifie le processus de déploiement d’applications sur Kubernetes en automatisant les tâches répétitives et en fournissant une gestion centralisée des configurations.

Le chart Helm vscode-python est un ensemble de fichiers de configuration qui facilite le déploiement d’application dans un envrionnement Kubernetes.

Déploiement sur Kube

Kubernetes (K8s) est un système open-source qui automatise le déploiement, la mise à l’échelle et la gestion d’applications conteneurisées. C’est un orchestrateur de conteneurs.

K8s récupére via le chart Helm toutes les infos nécessaires et déploie le conteneur (créé à partir de l’image Docker) sur l’infra du datalab.

    • File ➡️ New ➡️ Notebook

Pour vous aider, vous pouvez utiliser cette fonction qui génére une liste de booléens.

def crible_eratosthene(n) -> list[bool]:
    """Génère une liste de booléens où True indique qu'un nombre est premier."""

    est_premier = [True] * (n + 1)
    est_premier[0] = est_premier[1] = False  # 0 et 1 ne sont pas premiers

    for i in range(2, int(n**0.5) + 1):
        if est_premier[i]:
            for multiple in range(i * i, n + 1, i):
                est_premier[multiple] = False

    return est_premier
Tip

N’hésitez pas à créer plusieurs cellules pour découper votre code (petites icones avec des +)

Comme vous êtes un as de la programmation, cela ne vous prend que trois minutes. C’est beaucoup plus rapide que si vous aviez du installer Python, ainsi qu’un environnement d’exécution.

    • Notez le vous en aurez besoin à la fin

2.2 Utiliser des données

Fil rouge

Vous vous rendez compte qu’il faut plus de 8 kg de margarine et que vous n’en avez pas assez dans le frigo.

Félix propose d’aller en chercher à la superette du coin. Il entre dans l’ascenseur pour descendre les 6 étages et patatra, il se retrouve bloqué.

Pour retrouver les 5 chiffres du numéro du dépanneur, vous allez devoir répondre à 5 questions en requêtant le fichier des communes françaises.

COG

Chaque année, l’INSEE publie sur son site le Code officiel géographique (COG).

Ce référentiel regroupe, au 1er janvier, les codes et libellés des communes, cantons, arrondissements, départements, régions, ainsi que ceux des pays et territoires étrangers.

Vous allez utiliser via DuckDB du SQL dans du code Python. Commencez par importer le package et créer la vue vers le fichier des communes 2024.

import duckdb

duckdb.sql("""
CREATE OR REPLACE VIEW commune AS
FROM 'https://www.insee.fr/fr/statistiques/fichier/7766585/v_commune_2024.csv';
""")

Pour exécuter une requête :

duckdb.sql("""
SELECT *
  FROM commune
""")
Tip

Pour avoir un affichage plus joli, vous pouvez convertir la sortie en du dataframe pandas avec la méthode to_df().

import pandas as pd

duckdb.sql("""
SELECT *
  FROM commune
""").to_df()
    • Classez par nombre de communes décroissant
    • Quel est le numéro du département se classant au 20e rang ?
  • La somme des 5 nombres vaut 149
  • Les nombres sont dans l’ordre croissant

Vous venez ici d’utiliser des données disponibles sur internet. Vous pouvez également effectuer des traitements sur vos propres données en les stockant sur S3.

3 Stockage S3

Définition

S3 : Simple Storage System.

Inventé par Amazon, ce système de stockage est devenu l’outil standard du marché pour le stockage en ligne.

MinIO est une solution alternative de stockage d’objets open-source qui permet de déployer facilement un stockage évolutif et performant. Elle est compatible avec l’API S3 d’Amazon, ce qui facilite l’intégration avec les applications existantes.

Pour faire simple, vous pouvez vous dire que c’est comme si vous allez stocker vos fichiers dans un Drive.

Lorsque l’on travaille dans le cloud, il est essentiel de séparer les données des programmes pour :

  • mieux gérer les ressources
  • renforcer la sécurité en limitant les accès et les permissions
  • permettre une scalabilité indépendante des composants

MinIO offre :

  • une haute disponibilité
  • une sécurité renforcée grâce au chiffrement des données et des contrôles d’accès
  • des performances élevées, particulièrement adaptées aux environnements nécessitant un accès rapide aux données, comme le Big Data et l’intelligence artificielle

3.1 Votre bucket

Définition

Un bucket est un conteneur de stockage utilisé pour regrouper des objets (fichiers et métadonnées) dans des systèmes de stockage de type cloud. Il facilite l’organisation, la gestion des permissions et l’accès aux données dans un espace de stockage structuré.

Lors de votre création de compte, un bucket est créé avec votre nom d’utilisateur. Dans ce bucket, vous pouvez :

  • créer / supprimer des dossiers
  • importer / supprimer des fichiers

Vous avez plusieurs possibilités pour gérer à votre stockage :

3.2 Stocker vos fichiers

Fil rouge

Félix est sauvé, il peut maintenant aller chercher de la margarine et du papier cadeau (ça peut toujours servir).

En attendant, Josette s’occupe en confectionnant un superbe gilet gris avec son amie Thérèse.

Elle se souvient qu’elle a noté quelque part la longueur de fil nécessaire dans un fichier csv.

Ensuite, allez sur la page d’accueil du Datalab :

Chemin vers mes fichiers

Vous remarquerez à droite, des lignes de commande du type mc cp tp3-longueur-fil.parquet s3/<username>/ENSAI/SQL/tp3-longueur-fil.parquet.

Ce sont des commandes pour interagir avec votre stockage depuis un terminal (voir ci-après).

Cependant, vous pouvez extraire de ces commandes une information intéressante : le chemin vers votre fichier : s3/<username>/ENSAI/SQL/tp3-longueur-fil.parquet.

Vous venez de charger un fichier, voyons maintenant comment y accéder dans un Service, en utilisant par exemple le notebook que vous avez déjà lancé.

3.3 Utiliser des données

Sur la page d’accueil du Datalab :

Vous trouverez ici des informations pour vous connecter au stockage selon le language que vous utilisez : Python, R…

D’ailleurs pour chaque langage, il y a même plusieurs packages qui font le job. Par exemple s3fs ou boto3 pour Python.

Retournez dans votre service Notebook Jupyter :

    • vous pouvez par exemple le nommer S3.ipynb

Commencez par importer les packages nécessaires et récupérer les valeurs des variables d’environnement pour pouvoir se connecter à votre stockage.

import os
import polars as pl

s3_endpoint = f'https://{os.environ["AWS_S3_ENDPOINT"]}'
s3_access_key = os.environ["AWS_ACCESS_KEY_ID"]
s3_secret_access_key = os.environ["AWS_SECRET_ACCESS_KEY"]
s3_session_token = os.environ["AWS_SESSION_TOKEN"]
s3_region = os.environ["AWS_DEFAULT_REGION"]

s3_username = os.environ["VAULT_TOP_DIR"] # un peu bancal pour avoir le username
Warning

Les clés et les jetons ont une durée de vie limitée.

Si vous laissez votre service ouvert trop longtemps (pas bien !), vos clés et jetons pourraient être expirés.

Dans ce cas, vous pouvez recharger en dur les nouvelles valeurs (voir Mon Compte > Connexion au Stockage).

Définissez le chemin où se trouve votre fichier et lisez le avec Polars.

s3_file_path = f"s3://{s3_username}/ENSAI/SQL/tp3-longueur-fil.parquet"

storage_options = {
    "aws_endpoint":  s3_endpoint,
    "aws_access_key_id": s3_access_key,
    "aws_secret_access_key": s3_secret_access_key,
    "aws_token": s3_session_token,
    "aws_region": s3_region
  }

file = pl.scan_parquet(source=s3_file_path, 
                     storage_options=storage_options)
Polars

Polars est une bibliothèque rapide et performante pour la manipulation de données en Python et Rust, optimisée pour les grands volumes de données.

Contrairement à Pandas, Polars utilise une approche orientée colonnes (columnar) et tire parti du traitement parallèle, ce qui le rend particulièrement adapté pour les opérations analytiques lourdes.

Sa syntaxe, proche de celle de Pandas, permet des transformations, agrégations et manipulations de données avec des méthodes performantes et expressives.

Pour plus de détails : https://ssphub.netlify.app/post/polars/

    • Que se passe-t-il ?
Mode Lazy

Vous avez appelé la méthode scan_parquet() qui correspond au mode Lazy de Polars.

Le mode Lazy signifie que Polars va accumuler toutes les instructions que vous lui donnez sans pour autant les exécuter tout de suite.

Mais quel est l’intérêt ?

Imaginons que vous êtes en train d’analiser un trés gros fichier et que vous enchainez à la suite diverses opérations (filtres, sélections de colonnes, regroupements, agrégations, tri…), deux choix s’offrent à vous :

Option 1 (mode Eager : pl.read_parquet()):

  • vous chargez tout le fichier en RAM (dans la mémoire de votre machine)
  • vous appliquez des opérations dans n’importe quel ordre
  • vous lancez, c’est long et ça rame…

Option 2 (mode Lazy : pl.scan_parquet()):

  • vous scannez le fichier, i.e. analyser sa structure (types de colonnes) et ses métadonnées
  • vous donnez vos opérations dans n’importe quel ordre
  • à la fin, vous demandez à Polars de vous fournir le résultat
  • à ce moment, Polars va optimiser l’ordre des traitements en utilisant son propre plan d’exécution et vous donner une réponse beaucoup plus rapide

En résumé, en mode Eager, à chaque étape la machine effectue bêtement tous les calculs que vous lui demandez. En mode Lazy, la machine liste les opérations que vous demandez. Puis lorsque vous exigez un résultat, l’ordre des opérations est optimisé et la réponse est beaucoup plus rapide.

    • stockez le résultat dans une variable df

En appelant la méthode collect(), vous avez « forcé » Polars à charger les données en mémoire.

    • df.filter(pl.col("<column_name>") == "<value>")

3.4 Données d’autres utilisateurs

Fil rouge

Pendant que Josette confectionne son gilet, Félix revient avec la margarine.

Or, Josette n’a finalement plus faim. Félix se met alors à bouder et va s’enfermer dans les toilettes pour avaler des pilules qu’il a prises au passage à la pharmacie. Soudain, la mémoire lui revient !

Il se rappelle qu’ils avaient trouvé le prénom en parcourant… Le fichier des prénoms !

Ce fichier est stocké sur le bucket d’un autre utilisateur à l’une des adresses suivante :

  • SSP Cloud : s3://ludo2ne/diffusion/ENSAI/SQL-TP/prenoms-nat2022.parquet
  • Datalab du GENES : s3://ldeneuville-ensai/diffusion/ENSAI/SQL-TP/prenoms-nat2022.parquet
Important

Malheureusement sur le Datalab du GENES, la fonctionnalité n’est pas encore implémentée sur le Datalab du GENES.

Les dossiers diffusion de chaque utilisateur ne sont pas accessibles en lecture.

Ce n’est plus trop dans la philosophie de l’exercice, mais pour contourner le problème :

  • Téléchargez le fichier des prenoms
  • Stockez le sur votre S3
  • Utilisez ce fichier pour la suite
Diffusion

À la racine de votre Bucket, vous pouvez créer un dossier nommé diffusion.

Vous pourrez alors stocker à l’intérieur les dossiers et fichiers que vous souhaitez partager aux autres utilisateurs. Ils auront un droit d’accès en lecture sur votre dossier diffusion.

    • stockez-le dans une variable nommée fichier_prenoms
top10f2021 = fichier_prenoms\
    .filter((pl.col("sexe") == 2) & 
            (pl.col("annais") == "2021") & 
            (pl.col("preusuel") != "_PRENOMS_RARES"))\
    .group_by("preusuel")\
    .agg(pl.col("nombre").sum().alias("nombre_total"))\
    .sort("nombre_total", descending=True)\
    .limit(10)\
    .collect()
top10f2021_sql = fichier_prenoms\
    .sql("""
      SELECT preusuel, 
             SUM(nombre) AS nombre_total
        FROM self
       WHERE preusuel <> '_PRENOMS_RARES'
         AND annais = '2021'
         AND sexe = 2
       GROUP BY preusuel
       ORDER BY nombre_total DESC
       LIMIT 10
    """)\
    .collect()
Fil rouge

Alors que vous alliez chercher le prénom, votre camarade Katia vous demande en quelle année son prénom a été le plus donné entre 1960 et 1980.

prenom = "Katia"
annee_debut, annee_fin = 1960, 1980

df_prenom_annee = fichier_prenoms\
    .filter((pl.col("preusuel") == prenom.upper()) & 
            (pl.col("annais").str.to_integer(strict=False).is_not_null()) & 
            (pl.col("annais").str.to_integer(strict=False) >= annee_debut) & 
            (pl.col("annais").str.to_integer(strict=False) <= annee_fin))\
    .group_by("annais")\
    .agg(pl.col("nombre").sum().alias("nombre_total"))\
    .sort("annais")\
    .collect()

print(df_prenom_annee)

Vous pouvez également tracer un graphique avec ces données :

import matplotlib.pyplot as plt
import seaborn as sns

# Set seaborn style for a cleaner, more appealing look
sns.set_theme(style="whitegrid")

# Create the plot
fig, ax = plt.subplots(figsize=(10, 6))

# Data
years = df_prenom_annee["annais"].to_list()         # Extracts years as a list
counts = df_prenom_annee["nombre_total"].to_list()  # Extracts counts as a list

# Bar plot with custom colors and transparency for better visuals
ax.bar(years, 
       counts, 
       color="#4C72B0", 
       edgecolor="black", 
       alpha=0.8)

# Set labels and title with padding for readability
ax.set_xlabel("Année", fontsize=12, labelpad=10)
ax.set_ylabel("Nombre d'occurences", fontsize=12, labelpad=10)
ax.set_title(f"Occurrences du prénom {prenom} par année ({annee_debut}-{annee_fin})", fontsize=14, pad=15)

# Rotate x-axis labels, improve spacing, and format grid
ax.tick_params(axis='x', rotation=45)
plt.tight_layout()  # Adjust layout for tight fit

# Display the plot
plt.show()

Nous y sommes presque ! Pour trouver le fameux prénom :

  • Reprenez le résultat du nombre de nombres premiers entre 10 000 et 100 000
  • Otez 3
  • Divisez par 5

Le prénom recherché est à ce rang de classement pour les prénoms féminins donnés en France entre 1970 et 2000.

    • Filtrez les prénoms féminins donnés entre 1970 et 2000
    • Classez-les par le nombre de fois où ils ont été donné décroissant et prénom décroissant
    • Vous pouvez utiliser ce code : <df>.with_row_index()[<index_inf>:<index_sup>]

Ce n’est pas encore implémenté dans Polars, mais il est possible en SQL de générer les rangs : RANK() OVER (ORDER BY SUM(nombre) DESC) AS rang.

La réponse :

  • Commence par un S
  • Monsieur et Madame Hier ont une fille, comment s’appelle-t-elle ?

3.5 Exportez vos résultats vers MinIO

Vous pouvez également exporter vos fichiers vers S3.

Nous allons utiliser ici la librairie s3fs.

  • import s3fs
    
    fs = s3fs.S3FileSystem(
        client_kwargs={'endpoint_url': 'https://'+'minio-simple.lab.groupe-genes.fr'},
        key = os.environ["AWS_ACCESS_KEY_ID"], 
        secret = os.environ["AWS_SECRET_ACCESS_KEY"], 
        token = os.environ["AWS_SESSION_TOKEN"])
    
    destination = f"s3://{s3_username}/ENSAI/SQL/output.csv"
    
    with fs.open(destination, mode='wb') as f:
        top10f2021.write_csv(f)
    • le fichier output.csv a été généré
    • rafraichissez la page si besoin

Pour plus de détails sur le stockage des fichiers sur S3 :

Libérer les ressources

Une fois vos travaux terminés, il est temps de libérer les ressources réservées.

    • clic droit sur le nom du fichier ➡️ Download

Vous pouvez aisément reproduire votre travail plus tard :

  • Votre code est téléchargé
  • Vos données sont toujours sur MinIO
  • Il suffit de relancer un nouveau service et de relancer les calculs

Une manière plus propre de travailler est d’utiliser git pour versionner son code.

Fin du TP

Le but de ce TP était de vous faire découvrir les fonctionnalités de base du Datalab et les bonnes pratiques de travail dans un environnement Cloud.

Important

La suite du TP est optionnelle.

Elle est simplement donnée pour celles et ceux qui souhaient aller plus loin et profiter de toutes les fonctionnalités du Datalab.

Besoin d’assistance ?

  • Contactez l’équipe du SSP Cloud sur Slack
  • Pour le Datalab du GENES, vous trouverez sur la page d’accueil un lien pour rejoindre le canal Teams

Pour aller plus loin

Une présentation complète du projet Onyxia au Devoxx 2023, de sa philosophie et de son fonctionnement par Olivier LEVITT, Joseph GARRONE et Frédéric COMTE.

Une présentation plus courte

D’autres videos sur la page GitHub du projet

Bibliographie


4 Travailler avec Git

Caution

Sur le datalab, vos services ont une durée de vie limitée.

Pour sauvegarder vos programmes, la bonne pratique est d’utiliser un dépôt git. Nous allons donc créer et utiliser un jeton pour communiquer avec GitHub.

Pour suivre la démarche, il faut disposer d’un compte GitHub. Il est possible de suivre une démarche similaire avec GitLab.

4.1 Générer un token GitHub

Déjà fait ?

Si vous avez déjà généré et déclaré un jeton GitHub, inutile de refaire ces 2 étapes.

    • Renseigner :
      • nom du token : Datalab GENES
      • date d’expiration ➡️ Custom ➡️ 1 an
    • Cochez repo
    • Cliquez sur Generate token
    • Copiez ce jeton commençant par ghp_ et gardez le précieusement de côté quelques minutes
Warning
  • Ce jeton ne sera visible qu’une seule fois
  • si vous le perdez ou s’il est expiré, il faut en générer un nouveau

4.2 Déclarer votre jeton

GitHub vous a fournit un jeton. Il faut maintenant le déclarer sur le Datalab :

    • nom d’utilisateur Git
    • mail (celui utilisé pour votre compte GitHub)
Config Git

Vous pouvez maintenant échanger du code entre les services du Datalab et vos dépôts GitHub. 🎉

4.3 Dépôt pour le code

Avant de créer un service, nous allons créer un dépôt GitHub qui permettra de sauvegarder votre code.

    • Repository name : TP3-datalab
    • Private
    • Cochez Add a README file
    • .gitignore template : Python
    • Choose a license : Apache Licence 2.0
    • Create Repository

4.4 Branchez votre service sur un répo

Lors du lancement d’un Service, vous pouvez vous brancher sur un répo git. Ainsi le contenu de votre dépôt sera importé dans votre service.

Vous pourrez alors utiliser le code de votre dépôt et éventuellement le mettre à jour en effectuant un push.

Lancez un service Jupyter Notebook

    • De nombreux onglets permettent de configurer votre service
    • Service : possibilité d’utiliser une autre image Docker
    • Resources : choisir CPU et RAM
    • Init : script à lancer au démarrage

4.5 Sauver son code

    • File ➡️ New ➡️ Terminal
    • le fichier ex0.ipynb doit apparaître dans les Untracked files
    • Vous pouvez vérifier sur GitHub que votre fichier ex0.ipynb est bien présent
  • git add .
  • git commit -m "création fichier tp3"
  • git push

Exercice

Par exemple en important le fichier des prénoms avec Polars et en encapsulant du SQL :

    • 💡 Aide : SUM(CASE WHEN ? THEN ? ELSE ? END)

5 MinIO

D’autres possibilités pour accéder à votre stockage

5.1 Client MinIO

Le client MinIO installé et utilisable depuis le terminal permet également d’interagir avec vos fichiers.

Ouvrez un terminal (File ➡️ New ➡️ Terminal):

    • le fichier apparait dans votre explorer
    • Car importer les fichiers de données dans son espace de travail n’est pas une bonne pratique
Tip

La commande mc --help liste toutes les commandes possibles (ESPACE pour défiler, CTRL+C pour sortir)

5.2 Console Minio

Vous pouvez également accéder à votre stockage avec la console Minio :

5.3 Python et s3fs

import os
import s3fs
import polars as pl

fs = s3fs.S3FileSystem(
    client_kwargs={"endpoint_url": f"https://{os.environ['AWS_S3_ENDPOINT']}"},
    key = os.environ["AWS_ACCESS_KEY_ID"], 
    secret = os.environ["AWS_SECRET_ACCESS_KEY"], 
    token = os.environ["AWS_SESSION_TOKEN"])

s3_username = os.environ["VAULT_TOP_DIR"] # un peu bancal pour avoir le username

bucket_name = f"{s3_username}/diffusion/"

files = fs.ls(bucket_name)

for file in files:
    print(file)
!pip install humanize
import humanize

data = []

for file in fs.ls(bucket_name, detail=True):

    if file['type'] == 'directory':
        subfolder_files = fs.find(file['name'])
        file_count = len(subfolder_files)
        file_type = "Folder"
        size = None
    else:
        file_count = ""
        file_type = "File"
        size = file['size']
    
    data.append({
        "Name": os.path.basename(file['name']),
        "Type": file_type,
        "Size": size or 0,
        "Nb Files": file_count
    })

df = pl.DataFrame(sorted(
         data,
         key=lambda x: (
             0 if x["Type"] == "Folder" else 1,
             -x["Nb Files"] if x["Nb Files"] else 0,
             -x["Size"])
        ))\
        .with_columns(pl.col('Size').map_elements(lambda x: humanize.naturalsize(x, binary=True) if x else "", return_dtype=pl.String).alias('Size'))

print(f"Bucket : {bucket_name}", df, sep = "\n")

6 Surveiller son service

Vous arrivez sur la page de l’outil Grafana qui permet d’observer les métriques de votre service.

7 Les secrets

Enigme du Père Fouras

Plus j’ai de gardiens, moins je suis gardé.

Moins j’ai de gardiens, plus je suis gardé.

Qui suis-je ?

Certains éléments ne doivent pas être diffusés dans votre code (jetons d’accès, mots de passe…).

Pour éviter d’avoir à nettoyer votre code à chaque fois que vous le poussez sur GitHub, le datalab propose de gérer vos secrets.

7.1 Créer un secret

    • Nom : PATATE_TOKEN
    • Valeur : 123456
    • Cliquez sur pour valider
    • Nom : PATATE_PORT
    • Valeur : 5236
    • Cliquez sur pour valider

7.2 Utiliser dans un service

Dans votre servives, les deux variables d’environnement ont été créées.

  • import os
    
    token = os.environ["PATATE_TOKEN"]
    print(token)
Note

Ce TP avait pour but de vous familiariser avec le Datalab. Vous pouvez l’utiliser pour faire du Python, du R, créer une base de données (prochain TP) ou utiliser de nombreux autres outils.

8 Personnaliser son service

🚧

  • Utiliser un script d’initiation
  • Utilser sa propre image Docker