# Interaja com o Hub por meio da API de Filesystem

Além do [HfApi](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_api#huggingface_hub.HfApi), a biblioteca `huggingface_hub` oferece o [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem), uma interface de arquivos [compatível com fsspec](https://filesystem-spec.readthedocs.io/en/latest/) e pythonic para o Hugging Face Hub. O [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem) é construído sobre o [HfApi](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_api#huggingface_hub.HfApi) e oferece operações típicas de sistema de arquivos, como `cp`, `mv`, `ls`, `du`, `glob`, `get_file` e `put_file`.

> [!WARNING]
> [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem) oferece compatibilidade com fsspec, o que é útil para bibliotecas que a exigem (por exemplo, ler datasets e buckets do Hugging Face diretamente com `pandas`). No entanto, essa camada de compatibilidade introduz sobrecarga adicional. Para melhor desempenho e confiabilidade, recomenda-se usar os métodos de [HfApi](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_api#huggingface_hub.HfApi) sempre que possível.

## Uso

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

O argumento opcional `revision` pode ser passado para executar uma operação a partir de um commit específico, como um branch, nome de tag ou hash de commit. Observe que `revision` não é compatível com Buckets.

Diferentemente do `open` embutido do Python, o `open` do `fsspec` usa o modo binário, `"rb"`, por padrão. Isso significa que você deve definir explicitamente o modo como `"r"` para leitura e `"w"` para escrita em modo de texto. A adição a um arquivo (modos `"a"` e `"ab"`) ainda não é suportada.

## Listando repositórios grandes

Operações que listam arquivos de forma recursiva, como `find` e `glob`, precisam buscar todo o conteúdo do repositório. O Hub retorna essas entradas página por página, e uma página só pode ser solicitada após a anterior ter sido recebida: listar um repositório com 800 mil arquivos requer cerca de 800 solicitações sequenciais e, portanto, aproximadamente 30 minutos.

Para evitar isso, o [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem) lista repositórios grandes diretório por diretório, em paralelo:

```python
>>> from huggingface_hub import hffs

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

O número de solicitações simultâneas é controlado pelo argumento `max_workers` de [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem). O valor padrão é 16 e pode ser definido como 1 para desabilitar listagens paralelas. Observe que passar um `maxdepth` também acelera significativamente as listagens, pois o Hub retorna apenas as entradas que são efetivamente solicitadas.

## Mantenha as listagens atualizadas

Os diretórios são listados uma vez e seu conteúdo é armazenado em cache, portanto, um diretório que outra pessoa acabou de modificar não é detectado automaticamente. [HfFileSystem.invalidate_cache()](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem.invalidate_cache) descarta as listagens em cache, seja para um caminho (e seus pais) ou em todos os lugares quando chamado sem argumento:

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

Para buckets, o `huggingface_hub` pode fazer isso por você: o Hub transmite as alterações de arquivo de um bucket conforme elas ocorrem e o [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem) remove as listagens afetadas por uma alteração assim que ela chega. Ative com `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']
```

Ele também pode ser passado por meio do fsspec, com `fsspec.filesystem("hf", live_follow=True)` ou por meio do argumento `storage_options` das bibliotecas que aceitam um (pandas, arrow, ...).

Algumas coisas a saber sobre ele:

- **Somente buckets.** Repositórios de modelos, conjuntos de dados e espaços são repositórios git e o Hub não transmite suas alterações: passe `refresh=True` para [HfFileSystem.ls()](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem.ls) (ou use [HfApi.list_repo_tree()](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_api#huggingface_hub.HfApi.list_repo_tree)) para ver um novo commit.
- **Somente as listagens e os metadados que elas carregam são atualizados.** A leitura de um arquivo sempre solicita seu conteúdo do Hub, portanto, o acompanhamento ao vivo afeta apenas o que `ls`, `info`, `exists`, `glob`, ... relatam.
- O acompanhamento começa assim que um bucket é listado, e uma conexão em segundo plano é mantida aberta para cada bucket acompanhado, compartilhada por todas as instâncias de [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem). É por isso que a opção é opt-in.

## Integrações

O [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem) pode ser usado com qualquer biblioteca que integre o `fsspec`, desde que a URL siga o esquema:

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

O `repo_type_prefix` é `datasets/` para datasets, `spaces/` para Spaces, e os modelos não precisam de prefixo na URL.

Além dos repositórios, o [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem) também suporta Buckets do Hugging Face, que são um armazenamento de objetos semelhante ao S3 (veja [este guia](./buckets) para mais detalhes):

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

Algumas integrações interessantes em que o [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem) simplifica a interação com o Hub estão listadas abaixo:

* Lendo/gravando um DataFrame do [Pandas](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#reading-writing-remote-files) de/para um repositório do 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")
  ```

O mesmo fluxo de trabalho também pode ser usado para DataFrames do [Dask](https://docs.dask.org/en/stable/how-to/connect-to-remote-data.html) e do [Polars](https://pola-rs.github.io/polars/py-polars/html/reference/io.html).

* Querying Arquivos do Hub (remoto) com [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()
  ```

* Usando o Hub como um armazenamento de arrays com [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]
  ```

## Autenticação

Em muitos casos, é necessário estar conectado com uma conta do Hugging Face para interagir com o Hub. Consulte a seção [Autenticação](../quick-start#authentication) da documentação para saber mais sobre os métodos de autenticação no Hub.

Também é possível fazer login programaticamente passando seu `token` como argumento para [HfFileSystem](/docs/huggingface_hub/v2.4.0/pt/package_reference/hf_file_system#huggingface_hub.HfFileSystem):

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

Se você fizer login dessa forma, tenha cuidado para não vazar acidentalmente o token ao compartilhar seu código-fonte!

