# Interagir avec le Hub via l'API Filesystem

En plus de [HfApi](/docs/huggingface_hub/main/fr/package_reference/hf_api#huggingface_hub.HfApi), la bibliothèque `huggingface_hub` fournit [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem), une interface de fichiers [compatible fsspec](https://filesystem-spec.readthedocs.io/en/latest/) et pythonique pour le Hugging Face Hub. [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem) s’appuie sur [HfApi](/docs/huggingface_hub/main/fr/package_reference/hf_api#huggingface_hub.HfApi) et propose des opérations typiques d’un système de fichiers, telles que `cp`, `mv`, `ls`, `du`, `glob`, `get_file` et `put_file`.

> [!WARNING]
> [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem) offre une compatibilité avec fsspec, ce qui est utile pour les bibliothèques qui en ont besoin (par exemple, pour lire directement les jeux de données et les buckets Hugging Face avec `pandas`). Cependant, cette couche de compatibilité introduit un surcoût supplémentaire. Pour de meilleures performances et une meilleure fiabilité, il est recommandé d’utiliser les méthodes de [HfApi](/docs/huggingface_hub/main/fr/package_reference/hf_api#huggingface_hub.HfApi) lorsque c’est possible.

## Utilisation

```python
>>> from huggingface_hub import hffs

>>> # List all files in a dataset directory
>>> hffs.ls("datasets/my-username/my-dataset-repo/data", detail=False)
['datasets/my-username/my-dataset-repo/data/train.csv', 'datasets/my-username/my-dataset-repo/data/test.csv']

>>> # List all files in a bucket directory
>>> hffs.ls("buckets/my-username/my-bucket/experiment-data", detail=False)
['bucket/my-username/my-bucket/data/train-0000.parquet', 'bucket/my-username/my-bucket/data/train-0001.parquet', ...]

>>> # List all ".csv" files in a dataset repository
>>> hffs.glob("datasets/my-username/my-dataset-repo/**/*.csv")
['datasets/my-username/my-dataset-repo/data/train.csv', 'datasets/my-username/my-dataset-repo/data/test.csv']

>>> # Read a remote file
>>> with hffs.open("datasets/my-username/my-dataset-repo/data/train.csv", "r") as f:
...     train_data = f.readlines()

>>> # Read the content of a remote file as a string
>>> train_data = hffs.read_text("datasets/my-username/my-dataset-repo/data/train.csv", revision="dev")

>>> # Write a remote file
>>> with hffs.open("datasets/my-username/my-dataset-repo/data/validation.csv", "w") as f:
...     f.write("text,label")
...     f.write("Fantastic movie!,good")
```

L'argument facultatif `revision` peut être transmis pour exécuter une opération à partir d'un commit spécifique, tel qu'une branche, un nom de tag ou un hachage de commit. Notez que `revision` n'est pas compatible avec Buckets.

Contrairement à la fonction `open` intégrée de Python, la fonction `open` de `fsspec` utilise par défaut le mode binaire, `"rb"`. Cela signifie qu'il faut définir explicitement le mode sur `"r"` pour la lecture et sur `"w"` pour l'écriture en mode texte. L'ajout à un fichier (modes `"a"` et `"ab"`) n'est pas encore pris en charge.

## Lister les dépôts volumineux

Les opérations qui listent les fichiers de manière récursive, telles que `find` et `glob`, doivent récupérer l’intégralité du contenu du dépôt. Le Hub renvoie ces entrées page par page, et une page ne peut être demandée qu’une fois la précédente reçue : lister un dépôt contenant 800 k fichiers nécessite environ 800 requêtes séquentielles, soit environ 30 minutes.

Pour éviter cela, [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem) liste les grands dépôts répertoire par répertoire, en parallèle :

```python
>>> from huggingface_hub import hffs

>>> # Takes ~30s on a repository holding 800k files
>>> files = hffs.glob("datasets/allenai/objaverse/**/*.glb", maxdepth=3)
```

Le nombre de requêtes simultanées est contrôlé par l’argument `max_workers` de [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem). Sa valeur par défaut est 16 et il peut être défini à 1 pour désactiver les listings parallèles. Notez que le passage d’un `maxdepth` accélère également considérablement les listings, car le Hub ne renvoie alors que les entrées réellement demandées.

## Gardez les listes à jour

Les répertoires sont listés une seule fois et leur contenu est mis en cache, de sorte qu’un répertoire modifié par quelqu’un d’autre n’est pas pris en compte automatiquement. [HfFileSystem.invalidate_cache()](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem.invalidate_cache) supprime les listes mises en cache, soit pour un chemin donné (et ses parents), soit pour l’ensemble du système lorsqu’il est appelé sans argument :

```python
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False)  # listing is cached
>>> # ... another process uploads a file to the bucket ...
>>> hffs.invalidate_cache("buckets/my-username/my-bucket/data")
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False)  # listed again
['buckets/my-username/my-bucket/data/train.csv', 'buckets/my-username/my-bucket/data/new-file.csv']
```

Pour les buckets, `huggingface_hub` peut le faire pour vous : le Hub transmet en continu les modifications de fichiers d’un bucket au fur et à mesure qu’elles se produisent, et [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem) supprime les listes affectées par une modification dès son arrivée. Activez-le avec `live_follow=True` :

```python
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(live_follow=True)
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False)  # starts following that bucket
>>> # ... another process uploads a file to the bucket ...
>>> hffs.ls("buckets/my-username/my-bucket/data", detail=False)  # refreshed as changes arrive
['buckets/my-username/my-bucket/data/train.csv', 'buckets/my-username/my-bucket/data/new-file.csv']
```

Il peut également être transmis via fsspec, avec `fsspec.filesystem("hf", live_follow=True)` ou via l'argument `storage_options` des bibliothèques qui l'acceptent (pandas, arrow, ...).

Quelques points à connaître à ce sujet :

- **Buckets uniquement.** Les dépôts de modèles, de jeux de données et d’espaces sont des dépôts git et le Hub ne diffuse pas leurs modifications : passez `refresh=True` à [HfFileSystem.ls()](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem.ls) (ou utilisez [HfApi.list_repo_tree()](/docs/huggingface_hub/main/fr/package_reference/hf_api#huggingface_hub.HfApi.list_repo_tree)) pour voir un nouvel engagement.
- **Seules les listes et les métadonnées qu’elles contiennent sont actualisées.** La lecture d’un fichier demande toujours son contenu au Hub, de sorte que le suivi en direct n’affecte que ce que `ls`, `info`, `exists`, `glob`, ... rapportent.
- Le suivi démarre dès qu’un seau est listé, et une connexion d’arrière-plan est maintenue ouverte pour chaque seau suivi, partagée par toutes les instances de [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem). C’est pourquoi cette option est activée manuellement.

## Intégrations

Le [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem) peut être utilisé avec toute bibliothèque qui intègre `fsspec`, à condition que l’URL suive le schéma :

```
hf://[<repo_type_prefix>]<repo_id>[@<revision>]/<path/in/repo>
```

Le `repo_type_prefix` est `datasets/` pour les jeux de données, `spaces/` pour les Spaces, et les modèles n'ont pas besoin de préfixe dans l'URL.

En plus des dépôts, le [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem) prend également en charge les Buckets Hugging Face, qui constituent un stockage d’objets de type S3 (voir [ce guide](./buckets) pour plus de détails) :

```
hf://buckets/<bucket_id>/<path/in/bucket>
```

Voici quelques intégrations intéressantes dans lesquelles [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem) simplifie l’interaction avec le Hub :

* Lecture/écriture d'un DataFrame [Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#reading-writing-remote-files) depuis/vers un dépôt du Hub :

  ```python
  >>> import pandas as pd

  >>> # Read a remote CSV file into a dataframe
  >>> df = pd.read_csv("hf://datasets/my-username/my-dataset-repo/train.csv")
  >>> df = pd.read_csv("hf://buckets/my-username/my-bucket/train.csv")

  >>> # Write a dataframe to a remote CSV file
  >>> df.to_csv("hf://datasets/my-username/my-dataset-repo/test.csv")
  >>> df.to_csv("hf://buckets/my-username/my-bucket/test.csv")
  ```

Le même flux de travail peut également être utilisé pour les DataFrames [Dask](https://docs.dask.org/en/stable/how-to/connect-to-remote-data.html) et [Polars](https://pola-rs.github.io/polars/py-polars/html/reference/io.html).

* Querying Fichiers du Hub (distants) avec [DuckDB](https://duckdb.org/docs/guides/python/filesystems) :

  ```python
  >>> from huggingface_hub import HfFileSystem
  >>> import duckdb

  >>> fs = HfFileSystem()
  >>> duckdb.register_filesystem(fs)
  >>> # Query a remote file and get the result back as a dataframe
  >>> fs_query_file = "hf://datasets/my-username/my-dataset-repo/data_dir/data.parquet"
  >>> df = duckdb.query(f"SELECT * FROM '{fs_query_file}' LIMIT 10").df()
  ```

* Utiliser le Hub comme magasin de tableaux avec [Zarr](https://zarr.readthedocs.io/en/stable/tutorial.html#io-with-fsspec) :

  ```python
  >>> import numpy as np
  >>> import zarr

  >>> embeddings = np.random.randn(50000, 1000).astype("float32")

  >>> # Write an array to a repo
  >>> root = zarr.open_group("hf://my-username/my-model-repo/array-store", mode="w")
  >>> foo = root.create_group("embeddings")
  >>> foobar = foo.zeros(name="experiment_0", shape=(50000, 1000), chunks=(10000, 1000), dtype="f4")
  >>> foobar[:] = embeddings

  >>> # Read an array from a repo
  >>> root = zarr.open_group("hf://my-username/my-model-repo/array-store", mode="r")
  >>> first_row = root["embeddings/experiment_0"][0]
  ```

## Authentification

Dans de nombreux cas, vous devez être connecté avec un compte Hugging Face pour interagir avec le Hub. Reportez-vous à la section [Authentication](../quick-start#authentication) de la documentation pour en savoir plus sur les méthodes d’authentification sur le Hub.

Il est également possible de se connecter de manière programmatique en passant votre `token` en argument à [HfFileSystem](/docs/huggingface_hub/main/fr/package_reference/hf_file_system#huggingface_hub.HfFileSystem) :

```python
>>> from huggingface_hub import HfFileSystem
>>> hffs = HfFileSystem(token=token)
```

Si vous vous connectez de cette manière, prenez soin de ne pas divulguer accidentellement le jeton lors du partage de votre code source !

