# Compatibilidade com S3

Os Storage Buckets podem ser acessados por meio de uma **API compatível com S3**, permitindo o uso de ferramentas S3 existentes — o AWS CLI, `boto3`, `s5cmd` e a maioria dos outros SDKs S3 — em seus buckets sem alterar o código. As solicitações passam por um serviço de gateway em `https://s3.hf.co`.

A API S3 é uma das várias formas de acessar dados de buckets — para acesso nativo do Hugging Face (o CLI `hf`, caminhos `hf://` e montagens de sistema de arquivos) sem credenciais S3 separadas, consulte [Padrões de Acesso](./storage-buckets-access).

> [!NOTE]
> A API do S3 funciona apenas com [Storage Buckets](./storage-buckets). Ela não expõe outros tipos de repositório do Hugging Face (modelos, datasets, Spaces).

## Gerando credenciais do S3

O gateway autentica com chaves de acesso no estilo AWS derivadas de um [User Access Token](./security-tokens) do Hugging Face.

1. Acesse suas [Configurações de tokens de acesso](https://huggingface.co/settings/tokens). Crie um token com o botão **Criar novo token** se você ainda não tiver um. As permissões do token se tornam as permissões das credenciais do S3 — escolha **Leitura** para acesso somente leitura aos seus buckets, ou **Escrita** para acesso de leitura e escrita.
2. Encontre o token na lista, abra o menu suspenso correspondente e selecione **Generate S3 credentials**.

   
   
   
   

3. Copie o **ID da chave de acesso** gerada (com o prefixo `HFAK…`) e a **chave de acesso secreta** em um local seguro — a chave secreta é exibida apenas uma vez.

As credenciais do S3 herdam as permissões do token de acesso subjacente. Para tokens de granularidade fina, delimite-os apenas aos namespaces e buckets que você pretende usar.

> [!TIP]
> Para fluxos de trabalho automatizados que acessam os buckets de uma organização, você também pode gerar credenciais S3 a partir de um token de [service account](./enterprise-service-accounts#generating-s3-credentials) em vez de um User Access Token.

## Configurando um Cliente

Aponte seu cliente S3 para o endpoint do gateway e defina algumas opções obrigatórias. Use seu **namespace** do Hugging Face (seu nome de usuário ou o nome de uma organização) na URL do endpoint — consulte [Endereçamento de buckets](#addressing-buckets) abaixo.

| Configuração                        | Valor                          | Por quê                                                           |
|--------------------------------|--------------------------------|---------------------------------------------------------------|
| `endpoint_url`                 | `https://s3.hf.co/<namespace>` | O gateway, limitado ao seu namespace                         |
| `region`                       | `us-east-1`                    | Obrigatório; o gateway é atualmente de região única              |
| `s3.addressing_style`          | `path`                         | Os buckets são endereçados como segmentos de caminho, não como subdomínios        |
| `request_checksum_calculation` | `when_required`                | Impede que clientes recentes enviem somas de verificação finais       |
| `response_checksum_validation` | `when_required`                | Impede que clientes recentes esperem checksums nas respostas |

As duas configurações de verificação de integridade são importantes para clientes recentes: o AWS CLI ≥ 2.23 e as versões recentes do `boto3` enviam checksums CRC32 finais (por meio do emolduramento `aws-chunked`) por padrão, o que o gateway não interpreta. Essas configurações instruem o cliente a enviar checksums apenas quando uma operação os exige estritamente.

Os itens a seguir são opcionais, mas recomendados. Com o padrão do cliente de 8MB, um arquivo grande é dividido em muitas partes; 256MB significa muito menos partes por upload, enquanto cada parte permanece pequena o suficiente para o gateway processar de forma eficiente:

| Configuração                  | Valor   |
|--------------------------|---------|
| `s3.multipart_threshold` | `256MB` |
| `s3.multipart_chunksize` | `256MB` |

### Exemplo: perfil da AWS CLI

Adicione um perfil em `~/.aws/config`:

```ini
[profile hf]
region = us-east-1
endpoint_url = https://s3.hf.co/<namespace>
s3 =
    addressing_style = path
    multipart_threshold = 256MB
    multipart_chunksize = 256MB
request_checksum_calculation = when_required
response_checksum_validation = when_required
```
Observação: substitua o `<namespace>` acima pelo nome de usuário ou organização em que seus buckets estão armazenados.

Adicione as credenciais correspondentes ao perfil em `~/.aws/credentials`:

```ini
[hf]
aws_access_key_id = HFAK...
aws_secret_access_key = ...
```

Em seguida, use qualquer comando S3 com o perfil:

```bash
aws --profile hf s3 ls
aws --profile hf s3 mb s3://my-bucket
aws --profile hf s3 cp ./model.safetensors s3://my-bucket/models/model.safetensors
```

## Endereçamento de Buckets

O AWS S3 usa um espaço único e globalmente exclusivo de nomes de buckets, e os SDKs esperam que o nome do bucket seja uma string simples, sem `/`. Os buckets do Hugging Face, por outro lado, são identificados como `namespace/bucket`, em que o `namespace` é seu nome de usuário ou organização. Esse nível extra introduz uma incompatibilidade com os clientes S3 — muitos não aceitam um `/` no nome do bucket ou fazem a escape de URL incorretamente. Há duas formas de contornar isso:

**1. Coloque o namespace na URL do endpoint** (recomendado para a maioria dos casos). Isso limita todas as operações a esse namespace, de modo que o nome do bucket passado ao cliente é apenas o nome do bucket do HF. Funciona bem para seus próprios buckets ou para buckets em uma única organização, mas falha entre namespaces — por exemplo, uma cópia no servidor de um bucket pessoal para um bucket de organização.

```bash
aws --endpoint-url https://s3.hf.co/my-org s3api get-object \
  --bucket my-bucket --key some/object.txt ./object.txt
```

**2. Trate o namespace como o bucket** e acrescente o nome do bucket do HF à frente da chave do objeto. Isso funciona para operações em nível de objeto (envios, downloads), mas apresenta problemas com operações em nível de bucket, como a criação ou exclusão de buckets.

```bash
aws --endpoint-url https://s3.hf.co s3api get-object \
  --bucket my-org --key my-bucket/some/object.txt ./object.txt
```

## Limitações e Diferenças em relação ao AWS S3

Como os Storage Buckets não modelam todos os conceitos do S3, alguns comportamentos diferem ou não são suportados.

### Downloads de objetos

O gateway é atualmente de região única. Para melhorar o desempenho de download, o `GetObject` normalmente responde com um redirecionamento HTTP 302 para a borda mais próxima da CDN da Hugging Face, em vez de servir os bytes diretamente.

Alguns SDKs não seguem redirecionamentos de um endpoint S3, portanto o gateway detecta clientes que se identificam como `aws-cli`, `botocore` (o que abrange `boto3`) ou `aws-sdk-rust` e faz o proxy dos dados por si mesmo para eles. Todos os outros clientes (`rclone`, `s5cmd`, `curl`, o AWS Go SDK, etc.) recebem o 302 e o seguem nativamente, mantendo o gateway fora do caminho de dados para downloads mais rápidos.

### Nomeação de chaves de objeto

As chaves de objetos em buckets são mais restritas do que no S3. Uma chave **não deve**:

- começar ou terminar com `/`
- conter barras consecutivas (`//`)
- conter sequências `../`
- comece com `./`
- terminam com `..`
- contêm barras invertidas (`\`) ou bytes nulos (`\0`)

### ListObjects

- `ListObjectsV1` não é suportado — use `ListObjectsV2`. Observe que alguns clientes (como rclone) podem precisar ser configurados para usar exclusivamente `ListObjectsV2`.
- Apenas `/` é permitido como delimitador.

### Outras diferenças de API

- **Metadados do objeto**: metadados de usuário arbitrários (`x-amz-meta-*`) não são armazenados nem retornados. `Content-Type` é suportado.
- **Recursos não suportados**: ACLs, políticas de bucket, marcação de objetos, versionamento de objetos, regras de ciclo de vida, criptografia no lado do servidor (SSE) e notificações de bucket não são suportados. Os objetos são sempre reportados com a classe de armazenamento `STANDARD`. Os cabeçalhos e parâmetros de solicitação relacionados são aceitos, mas ignorados.
- **CopyObject**: a cópia no lado do servidor funciona apenas dentro de um único namespace. A cópia entre namespaces e `UploadPartCopy` (cópia de uma parte de um objeto existente para um upload multipart) não são suportadas.
- **Requisições condicionais**: as precondições `If-Match` / `If-None-Match` são respeitadas em `PutObject` e na origem de cópia de `CopyObject`, mas não em `GetObject`.
- **Expiração de upload multipart**: uploads multipart em andamento que nunca são concluídos ou abortados expiram e são limpos automaticamente após 7 dias.

## Exemplos

Receitas do mundo real para tarefas comuns. Cada uma se baseia na [configuração do cliente](#configuring-a-client) acima.

### Ler e escrever com `boto3`

[`boto3`](https://docs.aws.amazon.com/boto3/latest/) funciona com o gateway usando as [configurações do cliente](#configuring-a-client) acima. Substitua `<namespace>` pelo seu nome de usuário ou organização:

```python
import boto3
from botocore.config import Config

s3 = boto3.client(
    "s3",
    endpoint_url="https://s3.hf.co/<namespace>",
    aws_access_key_id="HFAK...",
    aws_secret_access_key="...",
    config=Config(
        region_name="us-east-1",
        s3={"addressing_style": "path"},
        request_checksum_calculation="when_required",
        response_checksum_validation="when_required",
    ),
)

s3.upload_file("model.safetensors", "my-bucket", "models/model.safetensors")
s3.download_file("my-bucket", "models/model.safetensors", "model.safetensors")
```

### Consulte um bucket com DuckDB

No DuckDB 2.0 ou posterior, a extensão `httpfs` lê caminhos `hf://buckets/` diretamente, e com a extensão `hf` também é possível gravar em Buckets. Consulte [Consultar com DuckDB](./storage-buckets-access#query-with-duckdb).

Para versões anteriores do DuckDB, ou para gravar os resultados de consultas de volta em um bucket com `COPY ... TO` sem a extensão, utilize o gateway S3:

```sql
INSTALL httpfs;
LOAD httpfs;

CREATE SECRET hf (
    TYPE s3,
    KEY_ID 'HFAK...',
    SECRET '...',
    ENDPOINT 's3.hf.co/<namespace>',
    URL_STYLE 'path',
    REGION 'us-east-1'
);

SELECT * FROM read_parquet('s3://my-bucket/data.parquet');
```

> [!NOTE]
> `URL_STYLE 'path'` é obrigatório. Sem ele, o DuckDB usa endereçamento no estilo virtual-hosted (`my-bucket.s3.hf.co`), que o gateway não atende — você verá um erro de "Could not resolve hostname".

### Importe dados usando `rclone`

[`rclone`](https://rclone.org/) é uma maneira conveniente de copiar dados entre dois armazenamento compatíveis com S3, por isso é uma boa opção para mover um bucket existente do AWS S3 (ou qualquer fonte compatível com S3) para um Storage Bucket.

> [!TIP]
> Movendo um conjunto de dados grande? Ao montar a origem e executar `hf sync`, a deduplicação é feita no cliente, o que geralmente resulta no envio de menos bytes do que com o rclone. Consulte o [Guia de Migração](./storage-buckets-migration).

A ideia é declarar dois remotos — seu bucket de origem e o gateway do Hugging Face — e deixar que o `rclone` transmita os objetos entre eles. Adicione ambos os remotos em `~/.config/rclone/rclone.conf`. O primeiro aponta para o seu bucket S3 existente; ajuste-o para corresponder à sua origem (aqui, AWS S3 puro):

```ini
[aws]
type = s3
provider = AWS
access_key_id = AKIA...
secret_access_key = ...
region = us-east-1
```

O segundo aponta para o gateway do Hugging Face. Como em qualquer outro cliente, delimite o endpoint ao seu [namespace](#addressing-buckets), use endereçamento por `path`, force ListObjectsV2 (a única versão de listagem suportada pelo gateway) e defina um tamanho de parte de 256M. Isso é muito maior que o padrão de 5M do rclone, então arquivos grandes são enviados em menos partes, e pequeno o suficiente para o gateway processar de forma eficiente e manter a memória do rclone sob controle (ele mantém 4 partes por transferência na memória):

```ini
[hf]
type = s3
provider = Other
endpoint = https://s3.hf.co/<namespace>
access_key_id = HFAK...
secret_access_key = ...
region = us-east-1
force_path_style = true
list_version = 2
upload_cutoff = 256M
chunk_size = 256M
```

Observação: substitua o `<namespace>` acima pelo nome de usuário ou organização em que seus buckets estão armazenados e use as [credenciais S3](#generating-s3-credentials) geradas a partir do seu token de acesso. O bucket de destino já deve existir sob esse namespace.

Agora, copie um bucket de origem para o seu Storage Bucket:

```bash
rclone copy aws:my-source-bucket hf:my-bucket --progress
```

`rclone copy` transfere apenas objetos que estão ausentes ou alterados no destino, portanto, é seguro reexecutar para retomar uma importação interrompida ou capturar novos objetos. Para tornar o destino um espelho exato da origem — excluindo objetos no destino que não existem mais na origem —, use `rclone sync` em vez disso:

```bash
rclone sync aws:my-source-bucket hf:my-bucket --progress
```

> [!TIP]
> Para importações grandes, adicione `--transfers` e `--checkers` para aumentar a concorrência (por exemplo, `--transfers 16 --checkers 16`) e execute `rclone check aws:my-source-bucket hf:my-bucket` em seguida para confirmar que todos os objetos foram transferidos.

### Versionar dados com DVC

[DVC](https://dvc.org/) versiona conjuntos de dados e modelos no git mantendo pequenos arquivos ponteiro no repositório e enviando os dados reais para um remoto. Um bucket funciona como um remoto do DVC por meio do gateway, de modo que seu código e os ponteiros `.dvc` permanecem no git, enquanto os dados ficam armazenados no seu bucket. Instale o DVC com suporte a S3 (`pip install 'dvc[s3]'`) e, em seguida, adicione o remoto usando as [configurações do cliente](#configuring-a-client) acima:

```bash
dvc remote add -d hf-bucket s3://my-bucket/dvc-store
dvc remote modify hf-bucket endpointurl https://s3.hf.co/<namespace>
dvc remote modify hf-bucket region us-east-1
```

Passe as [credenciais do S3](#generating-s3-credentials) por meio do ambiente, ou com `dvc remote modify --local` para que fiquem fora do git:

```bash
export AWS_ACCESS_KEY_ID=HFAK...
export AWS_SECRET_ACCESS_KEY=...
```

Em seguida, faça o rastreamento, o push e o pull como de costume — `dvc push` faz o upload para o bucket e `dvc pull` em um clone novo faz o download de volta:

```bash
dvc add data/
git add data.dvc .gitignore .dvc/config && git commit -m "Track data with DVC"
dvc push
```

> [!NOTE]
> Use seu [namespace](#addressing-buckets) em `endpointurl` e o nome do bucket sem prefixo na URL `s3://`.

