O S3 (Simple Storage Service) é o serviço de armazenamento de objetos da AWS: você joga arquivos lá dentro (imagens, backups, logs, vídeos, o que for), organizados em “buckets”, que funcionam mais ou menos como pastas raiz. É provavelmente o serviço mais usado da AWS, e é normalmente o primeiro contato de quem está começando na nuvem.
Neste post você vai criar seu primeiro bucket e subir arquivos nele de duas formas: pela linha de comando (AWS CLI) e por código Python (boto3, o SDK oficial da AWS para Python). No fim, você vai entender não só o “como”, mas também o porquê de cada passo.
Pré-requisitos
Antes de começar, você precisa de três coisas:
-
Uma conta AWS. Se ainda não tem, crie uma em aws.amazon.com. O S3 tem uma camada gratuita generosa, então testar os exemplos abaixo não deve custar nada.
-
AWS CLI instalada e configurada com suas credenciais:
aws configureIsso vai pedir sua Access Key, Secret Key, região padrão (ex:
us-east-1) e formato de saída. Se você ainda não tem uma Access Key, gere uma em IAM → Users → Security credentials, no console da AWS. -
Python 3.14 instalado, com o uv para gerenciar dependências e rodar os scripts:
uv add boto3==1.38.4Isso adiciona o boto3 (versão 1.38.4) ao
pyproject.toml/uv.lockdo projeto. Uma coisa boa de saber: o boto3 usa automaticamente as mesmas credenciais configuradas peloaws configure, então você não precisa configurar nada de novo para o Python: CLI e código Python “conversam” com a AWS da mesma forma.
Com isso pronto, vamos ao que interessa.
Criando o bucket via CLI
Antes do primeiro comando, duas regras de nome que valem para qualquer bucket S3:
- O nome é único globalmente, não só na sua conta. Ou seja, se alguém no mundo já usou o nome, você não consegue usar. Por isso é comum incluir algo único, como o nome da empresa ou um sufixo aleatório.
- Só letras minúsculas, números, pontos e hífens. Nada de espaço, maiúscula ou underline.
Com isso em mente, criar o bucket é um comando só:
# Criando um bucket
aws s3 mb s3://meu-bucket-exemplo-123 --region us-east-1
mb é de “make bucket”. O --region define em qual região física da AWS o
bucket vai morar. Vale escolher uma perto de quem vai consumir os dados,
por questão de latência (e, às vezes, de conformidade legal).
Se der certo, a CLI responde com:
make_bucket: meu-bucket-exemplo-123
Se quiser confirmar visualmente, dá pra abrir o console da AWS e ver o bucket na lista:
Subindo arquivos via CLI
Com o bucket criado, subir arquivo é o próximo passo. Para um arquivo
único, o comando é cp, igual ao cp do terminal, só que de local para o
S3:
# Upload de um arquivo
aws s3 cp arquivo.txt s3://meu-bucket-exemplo-123/
Quando você tem uma pasta inteira para subir, dá para rodar cp várias
vezes, mas o jeito certo é usar sync: ele compara o que já está no bucket
com o que está localmente e sobe só o que mudou. Isso importa principalmente
quando você roda o upload mais de uma vez: a segunda vez é bem mais rápida.
# Upload de uma pasta
aws s3 sync ./meus-arquivos s3://meu-bucket-exemplo-123/meus-arquivos
E para conferir se realmente subiu, você lista o conteúdo do bucket:
# Listando o conteúdo do bucket
aws s3 ls s3://meu-bucket-exemplo-123/
Se o arquivo aparecer na lista com o tamanho certo, deu tudo certo. No console, entrando no bucket, o arquivo aparece listado junto com o tamanho e a data de upload:
Criando o bucket via boto3
Tudo que fizemos até aqui pela CLI também dá para fazer por código, o que importa quando você quer automatizar isso dentro de uma aplicação, em vez de rodar comando manualmente.
# criar_bucket.py
import boto3
s3 = boto3.client("s3", region_name="us-east-1")
s3.create_bucket(Bucket="meu-bucket-exemplo-123")
Repare que a lógica é a mesma do comando mb: um cliente do S3, apontando
para uma região, criando um bucket com nome único. Para rodar:
uv run criar_bucket.py
Se a sua região não for us-east-1, o create_bucket exige um parâmetro
a mais, senão a AWS retorna erro. É uma particularidade histórica da
API do S3, então vale decorar:
s3.create_bucket(
Bucket="meu-bucket-exemplo-123",
CreateBucketConfiguration={"LocationConstraint": "sa-east-1"},
)Subindo arquivos via boto3
Com o bucket criado, o upload em Python usa o método upload_file:
# upload.py
import boto3
s3 = boto3.client("s3")
s3.upload_file("arquivo.txt", "meu-bucket-exemplo-123", "arquivo.txt")
uv run upload.py
Os três argumentos, na ordem, são: caminho do arquivo local, nome do bucket
e a “key” (o caminho/nome que o arquivo vai ter dentro do bucket). É esse
terceiro argumento que dá a flexibilidade de organizar os arquivos. Se você
quiser simular uma “pasta” dentro do bucket (o S3 não tem pastas de verdade,
só simula visualmente a partir do nome), basta usar / na key:
s3.upload_file("arquivo.txt", "meu-bucket-exemplo-123", "backups/arquivo.txt")
E, assim como fizemos na CLI, dá para conferir os arquivos que estão no bucket:
# listar.py
import boto3
s3 = boto3.client("s3")
response = s3.list_objects_v2(Bucket="meu-bucket-exemplo-123")
for obj in response.get("Contents", []):
print(obj["Key"])
uv run listar.py
Esse script imprime a key de cada objeto do bucket: é o list_objects_v2
que faz o trabalho de listar, e o for só percorre o resultado.
Duas observações importantes
-
O bucket é privado por padrão. A AWS ativa o Block Public Access automaticamente, então ninguém acessa os arquivos por URL pública a menos que você mude isso explicitamente. É o comportamento certo pra maioria dos casos: só desative se você realmente souber o que está fazendo (por exemplo, hospedar um site estático). Você confere isso na aba “Permissions” do bucket, em “Block public access”:
(espaço reservado para print: aba Permissions com o Block Public Access ativado)
-
Apague o bucket depois do teste. Bucket de teste esquecido é uma das formas mais comuns de gerar custo desnecessário na AWS. Para apagar:
aws s3 rb s3://meu-bucket-exemplo-123 --forceO
--forceremove os objetos dentro do bucket antes de apagar o bucket em si. Sem ele, o comando falha se o bucket não estiver vazio.
Recapitulando
Você criou um bucket e subiu arquivos nele de duas formas: CLI para o dia a dia manual, boto3 para automatizar dentro de código Python. É a mesma lógica por trás de praticamente tudo que se faz com S3: criar um cliente (ou usar a CLI já configurada), apontar para uma região e um bucket, e chamar o método certo para a ação que você quer.
Continuando
O S3 raramente vive sozinho. Onde ele fica mais interessante é quando entra num pipeline com outros serviços: alimentando um crawler do Glue, sendo consultado via Athena ou processado por uma função Lambda em resposta a novos objetos.
É esse pipeline serverless (S3, Lambda, Glue e Athena) que eu cubro no curso
Engenharia de dados: AWS, Python e B3 na prática.
Caso queira, utilize o cupom ARQUITECLOUD para garantir 50% de desconto na compra.