# Filesystem API を使用して Hub と対話する

[HfApi](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi)に加えて、`huggingface_hub`ライブラリは、Hugging Face HubへのPython的な[fsspec互換](https://filesystem-spec.readthedocs.io/en/latest/)ファイルインターフェースである[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem)を提供します。[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem)は[HfApi](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi)を基盤として構築されており、`cp`、`mv`、`ls`、`du`、`glob`、`get_file`、`put_file`といった典型的なファイルシステムスタイルの操作を提供します。

> [!WARNING]
> [HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem) は fsspec 互換性を提供しており、これを必要とするライブラリ（`pandas` を用いて Hugging Face のデータセットやバケットを直接読み込む場合など）で有用です。ただし、この互換性レイヤーにより追加のオーバーヘッドが発生します。パフォーマンスと信頼性を高めるため、可能な場合は [HfApi](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi) のメソッドを使用することをお勧めします。

## 使用方法

```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")
```

オプションの`revision`引数を渡すことで、ブランチ、タグ名、コミットハッシュなどの特定のコミットから操作を実行できます。`revision`はBucketsと互換性がないことに注意してください。

Pythonの組み込みの`open`とは異なり、`fsspec`の`open`はデフォルトでバイナリモードの`"rb"`になります。そのため、テキストモードで読み取りには`"r"`、書き込みには`"w"`を明示的に設定する必要があります。ファイルへの追記（モード`"a"`および`"ab"`）は現在サポートされていません。

## 大規模リポジトリのリスト表示

`find` や `glob` のようなファイルを再帰的に列挙する操作では、リポジトリの全コンテンツを取得する必要があります。Hub はこれらのエントリをページ単位で返却しますが、前のページを受信した後にのみ次のページをリクエストできます。そのため、80万ファイルを含むリポジトリの列挙には約800回のシーケンシャルなリクエスト、つまり約30分かかります。

それを避けるために、[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem) は大規模なリポジトリをディレクトリごとに並列で列挙します:

```python
>>> from huggingface_hub import hffs

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

並行リクエストの数は、[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem)の`max_workers`引数で制御されます。デフォルト値は16ですが、1に設定することで並列リスト表示を無効にできます。なお、`maxdepth`を渡すこともリスト表示を大幅に高速化します。これは、Hubが実際にリクエストされたエントリのみを返すようになるためです。

## リストの鮮度を保つ

ディレクトリは一度のみ列挙され、その内容はキャッシュされるため、他のユーザーが変更したばかりのディレクトリは自動的に反映されません。[HfFileSystem.invalidate_cache()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem.invalidate_cache) は、キャッシュされた列挙情報を破棄します。引数なしで呼び出すとすべてのパス、引数を指定するとそのパス（および親ディレクトリ）の列挙情報が破棄されます。

```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']
```

バケットの場合、`huggingface_hub`がこれを行います。Hubはバケットのファイル変更をリアルタイムでストリーミングし、[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem)は変更が届くとすぐに、その変更の影響を受けたリストを破棄します。`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']
```

また、`fsspec.filesystem("hf", live_follow=True)` を通して、または引数を受け付けるライブラリ（pandas、arrow など）の `storage_options` 引数を通じて渡すこともできます。

これについて知っておくべきこと:

- **バケットのみ。**モデル、データセット、スペースのリポジトリは git リポジトリであり、Hub はそれらの変更をストリーミングしません。新しいコミットを確認するには、[HfFileSystem.ls()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem.ls) に `refresh=True` を渡すか、[HfApi.list_repo_tree()](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_api#huggingface_hub.HfApi.list_repo_tree) を使用してください。
- **更新されるのは、リスト表示とそのメタデータのみです。** ファイルの読み取りでは常に Hub からそのコンテンツを要求するため、ライブフォローが影響するのは、`ls`、`info`、`exists`、`glob`、... が報告する内容のみです。
- バケットがリストされた時点でフォローが開始され、フォロー中の各バケットにつき1つのバックグラウンド接続が常時開かれた状態に保たれます。この接続はすべての[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem)インスタンスで共有されます。そのため、このオプションはオプトイン方式となっています。

## 統合

`fsspec` と統合されているライブラリであれば、URL が以下のスキームに従っている限り、[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem) を使用できます:

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

`repo_type_prefix` は、データセットの場合は `datasets/`、Spaces の場合は `spaces/` であり、モデルは URL にプレフィックスを付ける必要はありません。

リポジトリに加えて、[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem)はHugging Face Bucketsもサポートしています。これはS3のようなオブジェクトストレージです（詳細は[このガイド](./buckets)を参照してください）：

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

[HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem) を使用して Hub とのやり取りを簡素化できる、いくつかの興味深い統合を以下に示します。

* Hubリポジトリから[Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#reading-writing-remote-files) DataFrameを読み込む/書き出す:

  ```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")
  ```

同じワークフローは、[Dask](https://docs.dask.org/en/stable/how-to/connect-to-remote-data.html)および[Polars](https://pola-rs.github.io/polars/py-polars/html/reference/io.html)のDataFrameにも使用できます。

* Querying （リモート）[DuckDB](https://duckdb.org/docs/guides/python/filesystems)による Hub ファイル:

  ```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()
  ```

* [Zarr](https://zarr.readthedocs.io/en/stable/tutorial.html#io-with-fsspec)をアレイストアとしてHubを使用する:

  ```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]
  ```

## 認証

多くの場合、Hubとやり取りするにはHugging Faceアカウントでログインする必要があります。Hubでの認証方法の詳細については、ドキュメントの[Authentication](../quick-start#authentication)セクションを参照してください。

`token` を [HfFileSystem](/docs/huggingface_hub/v2.4.0/ja/package_reference/hf_file_system#huggingface_hub.HfFileSystem) の引数として渡すことで、プログラム的にもログインできます。

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

この方法でログインする場合は、ソースコードを共有する際にトークンを誤って漏洩しないよう注意してください！

