# Stockage de données

## Principes

La solution de stockage de fichiers associée au Datalab est <a href="https://min.io" target="_blank">MinIO</a>, un système de stockage d'objets basé sur le cloud, compatible avec l'API S3 d'Amazon. Concrètement, cela a plusieurs avantages :

* les fichiers stockés sont accessibles facilement et à n'importe quel endroit : un fichier est accessible directement via une simple URL, qui peut être partagée ;
* il est possible d'accéder aux fichiers stockés directement dans les services de _data science_ (R, Python...) proposés sur le Datalab, sans avoir besoin de copier les fichiers localement au préalable, ce qui améliore fortement la reproductibilité des analyses.

![MinIO Schema](/img/minio.svg)

## Gérer ses données

### Importer des données

La page <a href="https://onyxia.lab.groupe-genes.fr/my-files" target="_blank">Mes fichiers</a> du Datalab prend la forme d'un explorateur de fichiers présentant les différents _buckets_ (dépôts) auxquels l’utilisateur a accès.

Chaque utilisateur dispose par défaut d'un _bucket_ personnel pour stocker ses fichiers. Au sein de ce _bucket_, deux options sont possibles :

* "**créer un répertoire**" : crée un répertoire dans le _bucket_/répertoire courant, de manière hiérarchique, comme dans un système de fichiers traditionnel ;
* "_**uploader**_** un fichier**" : _upload_ un ou plusieurs fichiers dans le répertoire courant.

::: {.callout-note}
L'interface graphique du stockage de données sur le Datalab est encore en cours de construction. Elle peut à ce titre présenter des problèmes de réactivité. Pour des opérations fréquentes sur le stockage de fichiers, il peut être préférable d'interagir avec MinIO via le terminal.
:::

### Partager des données

En cliquant sur un fichier dans son _bucket_ personnel, on accède à sa page de caractéristiques. Sur celle-ci, il est notamment possible de **changer le statut de diffusion du fichier**. Changer le statut du fichier de "privé" à "public" permet d'obtenir un **lien de diffusion**, qui peut alors être transmis pour téléchargement du fichier. Le statut "public" ne donne aux autres utilisateurs que des droits en lecture, la modification ou la suppression de fichiers personnels par d'autres utilisateurs est impossible.

Pour simplifier la mise à disposition en lecture de plusieurs fichiers — dans le cadre d'une formation par exemple — il est possible de créer un **dossier "diffusion"** dans son _bucket_ personnel. Par défaut, tous les fichiers présents dans ce dossier ont un statut de diffusion public.

::: {.callout-note}
Dans le cadre de projets collaboratifs, il peut être intéressant pour les différents participants d'avoir accès à un espace de stockage commun. Il est possible pour cet usage de créer des _buckets_ partagés sur MinIO. N'hésitez pas à nous contacter sois sur notre teams <a href="https://teams.microsoft.com/l/team/19%3Ak2a7PAYG-0EO6vmypa7sBdB5hXUR5c3YBDcszO0wCe41%40thread.tacv2/conversations?groupId=050057b4-2f34-4149-9084-5cd8f14b48e5&tenantId=99578065-47e8-4c36-bbf8-4e1228cfb056" target="_blank">ici Datalab - GENES - Teams</a> ou via notre mail support à l’adresse support.informatique@ensae.fr si vous souhaitez porter des projets _open-data_ sur le Datalab.
:::

<a href="https://onyxia.lab.groupe-genes.fr/my-files" target="_blank">

::: {.callout-warning}
Conformément aux <a href="https://www.sspcloud.fr/tos\_fr.md" target="_blank">conditions d'utilisation</a>, seuls des données de type _open data_ ou ne présentant aucune sensibilité peuvent être stockées sur le Datalab. Le fait qu'un fichier ait un statut de diffusion "privé" ne suffit pas à garantir une parfaite confidentialité.
:::

## Utiliser des données stockées sur MinIO

Les identifiants d'accès nécessaires pour accéder à des données sur MinIO sont pré-configurés dans les différents services du Datalab, accessibles sous la forme de [variables d'environnement](secrets.qmd). Ainsi, l'import et l'export de fichiers à partir des services est grandement facilité.

L'accès au stockage MinIO est possible via un token (jeton d'accès) personnel, valide 7 jours, et automatiquement régénéré à échéances régulières sur le SSP Cloud. Lorsqu'un token a expiré, les services créés avant la date d'expiration (avec le précédent token) ne peuvent plus accéder au stockage ; le service concerné apparaît alors marqué en rouge dans la page Mes Services. Il est donc primordial de renouveler régulièrement les services en cours d'exécution, en prenant soin de sauvegarder au préalable son code et ses données. 


### Configuration

::: {.panel-tabset}

#### R

En R, l'interaction avec un système de fichiers compatible S3 est rendu possible par la librairie `aws.s3`.

```r
library(aws.s3)
```

#### Python (avec Jupyter ou VSCode)

En Python, l'interaction avec un système de fichiers compatible S3 est rendu possible par deux librairies :

* <a href="https://boto3.amazonaws.com/v1/documentation/api/latest/index.html" target="_blank">Boto3</a>, une librairie créée et maintenue par Amazon ;
* <a href="https://s3fs.readthedocs.io/en/latest/" target="_blank">S3Fs</a>, une librairie qui permet d'interagir avec les fichiers stockés à l'instar d'un _filesystem_ classique.

Pour cette raison et parce que S3Fs est utilisée par défaut par la librairie <a href="https://pandas.pydata.org" target="_blank">pandas</a> pour gérer les connections S3, nous allons présenter la gestion du stockage sur MinIO via Python à travers cette librairie.

```python
import os
import s3fs

# Create filesystem object
S3_ENDPOINT_URL = "https://" + os.environ["AWS_S3_ENDPOINT"]
fs = s3fs.S3FileSystem(client_kwargs={'endpoint_url': S3_ENDPOINT_URL})
```

#### mc

MinIO propose un client en ligne de commande (`ùc`) qui permet d’interagir avec le système de stockage à la manière d'un _filesystem_ UNIX classique. Ce client est installé par défaut et accessible via un terminal dans les différents services du Datalab.

Le client MinIO propose les commandes UNIX de base, telles que ls, cat, cp, etc. La liste complète est disponible dans la <a href="https://docs.min.io/docs/minio-client-complete-guide.html" target="_blank">documentation du client</a>.

:::

### Lister les fichiers d'un *bucket*

::: {.panel-tabset}

#### R

```r
aws.s3::get_bucket("donnees-insee", region = "")
```

#### Python

```python
fs.ls("donnees-insee")
```

#### mc

Le stockage du Datalab est accessible via l'alias `s3`. Par exemple, pour lister les fichiers du bucket `donnees-insee` :

```bash
mc ls s3/donnees-insee
```

:::

### Importer des données

::: {.panel-tabset}

#### R

```r
BUCKET <- "donnees-insee"
FILE_KEY_S3 <- "diffusion/BPE/2019/BPE_ENS.csv"

df <- 
  aws.s3::s3read_using(
    FUN = readr::read_delim,
    # Mettre les options de FUN ici
    delim = ";",
    object = FILE_KEY_S3,
    bucket = BUCKET,
    opts = list("region" = "")
  )
```

#### Python

Le package S3Fs permet d'interagir avec les fichiers stockés sur MinIO comme s'il s'agissait de fichiers locaux. La syntaxe est donc très familière pour les utilisateurs de Python. Par exemple, pour importer/exporter des données tabulaires via `pandas` :

```python
import pandas as pd

BUCKET = "donnees-insee"
FILE_KEY_S3 = "diffusion/BPE/2019/BPE_ENS.csv"
FILE_PATH_S3 = BUCKET + "/" + FILE_KEY_S3

with fs.open(FILE_PATH_S3, mode="rb") as file_in:
    df_bpe = pd.read_csv(file_in, sep=";")
```

#### mc

Pour copier les données d'un bucket sur MinIO vers le service local :

```bash
mc cp s3/donnees-insee/diffusion/BPE/2019/BPE_ENS.csv ./BPE_ENS.csv
```

::: {.callout-warning}
**Copier les fichiers dans le service local n'est généralement pas une bonne pratique** : cela limite la reproductibilité des analyses, et devient rapidement impossible avec des volumes importants de données. Il est donc préférable de prendre l'habitude d'importer les données comme des fichiers directement dans `R`/`Python`.
:::

:::

### Exporter des données vers MinIO

::: {.panel-tabset}

#### R

```r
BUCKET_OUT = "<mon_bucket>"
FILE_KEY_OUT_S3 = "mon_dossier/BPE_ENS.csv"

aws.s3::s3write_using(
    df,
    FUN = readr::write_csv,
    object = FILE_KEY_OUT_S3,
    bucket = BUCKET_OUT,
    opts = list("region" = "")
)
```

#### Python

```python
BUCKET_OUT = "<mon_bucket>"
FILE_KEY_OUT_S3 = "mon_dossier/BPE_ENS.csv"
FILE_PATH_OUT_S3 = BUCKET_OUT + "/" + FILE_KEY_OUT_S3

with fs.open(FILE_PATH_OUT_S3, 'w') as file_out:
    df_bpe.to_csv(file_out)
```

#### mc

Pour copier les données du service local vers un bucket sur MinIO:

```bash
mc cp chemin/local/vers/mon/fichier.csv s3/<mon_bucket>/chemin/distant/vers/mon/fichier.csv
```

:::

### Renouveler des jetons d'accès (*tokens*) périmés

L'accès au stockage MinIO est possible via un _token_ (jeton d'accès) personnel, valide 24h, et automatiquement régénéré à échéances régulières sur le SSP Cloud. Lorsqu'un token a expiré, les services créés avant la date d'expiration (avec le précédent token) ne peuvent plus accéder au stockage ; le service concerné apparaît alors marqué en rouge dans la page <a href="https://onyxia.lab.groupe-genes.fr/my-services" target="_blank">Mes Services</a>. Dans ce cas, deux possibilités :
- ouvrir un nouveau service sur le Datalab, qui aura par défaut un nouveau token à jour
- remplacer manuellement les jetons périmés par des nouveaux. Des scripts indiquant la manière de faire pour les différentes utilisations de MinIO (`R`/`Python`/`mc`) sont disponibles <a href="https://onyxia.lab.groupe-genes.fr/account/storage" target="_blank">ici</a>. Il suffit de choisir le script pertinent et de l'exécuter dans son environnement de travail courant.





