Manipulando buckets e objetos do Amazon S3 com Python

O Python é umas das linguagens de programação mais versáteis que existe, podendo ser utilizado tanto em sistemas de alta complexidade, quanto scripts para automação de tarefas. Neste artigo vamos mostrar de maneira simplificada como manipular bucket e objetos do Amazon S3 com Python.

Antes de iniciarmos no código você precisa ter suas credenciais AWS devidamente configuradas no seu ambiente usando aws_access_key_id e aws_secret_access_key.

Além do Python, você precisa ter instalado em seu ambiente o SDK para Python da Amazon, o boto3. Veja esta documentação para fazer a instalação em seu ambiente.

O Amazon Simple Storage Service (Amazon S3) é um serviço de armazenamento de objetos que oferece escalabilidade, disponibilidade de dados, segurança e performance (Fonte: AWS S3).

Abaixo listamos as classes de armazenamento disponíveis atualmente:

S3 Standard
S3 Intelligent-Tiering
S3 Standard-IA
S3 One Zone-IA
S3 Glacier Instant Retrieval
S3 Glacier Flexible Retrieval
S3 Glacier Deep Archive
S3 Outposts

Neste artigo vamos considerar apenas a classe S3 Standard.

Criar bucket

O primeiro passo para armazenar dados no S3 é a criação de buckets. Será dentro deles que os objetos serão armazenados.

Embora não seja correto chamar de pastas e arquivos, é possível criar uma estrutura semelhante em que um objeto agrupa outros objetos por meio de um prefixo no nome. Portanto se criarmos os objetos com os nomes htmls/index.html e htmls/robots.txt, na prática teremos uma pasta chamada htmls e dentro os arquivos index.html e robots.txt.

É hora de colocar a mão na massa.

Crie um arquivo chamado s3.py com o seguinte conteúdo:

import boto3
import pprint
from botocore.exceptions import ClientError

def create_bucket(bucket_name, region):
    try:
        s3_client = boto3.client('s3', region_name=region)
        location = {'LocationConstraint': region}
        pprint.pprint(s3_client.create_bucket(Bucket=bucket_name, CreateBucketConfiguration=location)) #Usamos o pprint para uma saída mais amigável do resultado.
    except ClientError as e:
        print(e)

create_bucket("hello-bucket-python", "sa-east-1")

Ao executar o código você deverá obter o seguinte retorno:

Veja que o comando foi executado com sucesso e na resposta temos a URL do bucket recém criado: http://hello-bucket-python.s3.amazon.aws.com/.

Listar Buckets

Próximo passo é listar todos os buckets no qual a conta que você está usando tem acesso.

Edite o arquivo s3.py e substitua o conteúdo pelo seguinte:

import boto3
import pprint

def list_buckets():

    s3_client = boto3.client('s3')
    response = s3_client.list_buckets()

    for bucket in response['Buckets']: #Para cada bucket, fazemos um looping para exibir os dados.
        pprint.pprint(bucket) #Usamos o pprint para uma saída mais amigável do resultado.

list_buckets()

O resultado é a exibição do nome dos buckets que você tem acesso:

Deletar bucket

Para finalizar a manipulação básica dos buckets, vamos deleta-lo.

Edite o arquivo s3.py e substitua o conteúdo pelo seguinte:

import boto3
import pprint
from botocore.exceptions import ClientError

def delete_bucket(bucket_name):
    try:
        s3_client = boto3.resource('s3')
        bucket = s3_client.Bucket(bucket_name)
        pprint.pprint(bucket.delete()) #Usamos o pprint para uma saída mais amigável do resultado.
    except ClientError as e:
        print(e)

delete_bucket("hello-bucket-python")

Observe que o comando foi executado com sucesso e o bucket foi removido.

⚠️ IMPORTANTE: Só é possível remover bucket vazios, ou seja, sem qualquer objeto dentro dele. Caso contrário a AWS retorna um erro BucketNotEmpty.

Upload de objeto

Os objetos são comumente chamados de pastas e arquivos devido a sua estrutura parecida com aquelas que vimos em sistemas de arquivos, no entanto podem ser chamados também de nome de chave (keyname).

Crie novamente o bucket que criamos no início deste artigo para que possamos adicionar objetos.

Vamos usar um arquivo chamado exemplo.txt criado da seguinte forma:

Edite o arquivo s3.py e substitua o conteúdo pelo seguinte:

import boto3
from botocore.exceptions import ClientError

def upload_object(bucket_name, keyname, file_to_upload):
    try:
        s3_client = boto3.client('s3')
        response = s3_client.upload_file(
            Filename=file_to_upload,
            Bucket=bucket_name, 
            Key=keyname,
            ExtraArgs={"Tagging": "Project=ZZZ&Area=AAA"}
        )
    except ClientError as e:
        print(e)

# Passamos por parametro o nome do bucket, nome da chave e path do arquivo local
upload_object("hello-bucket-python", "exemplo.txt", "exemplo.txt")

Nesse caso não tem retorno em caso de sucesso. Se o upload não for realizado, será retornada mensagem de erro informando o motivo.

Importante observar que o parâmetro keyname deve contar o nome/caminho completo. Portanto se deseja criar uma estrutura de pastas, a keyname deve ser algo como meuarquivos/exemplo.txt.

⚠️ Ao fazer upload em objetos/keynames existentes, ele será substituído no bucket.

Listar objetos

Agora vamos listar os objetos para certificar de que realmente está la.

Edite o arquivo s3.py e substitua o conteúdo pelo seguinte:

import boto3
import pprint
from botocore.exceptions import ClientError

def list_objects(bucket_name):
    try:
        s3_client = boto3.resource('s3')
        bucket = s3_client.Bucket(bucket_name)
                # Para cada objeto encontrado, vamos mostraro nome/keyname
        for obj in bucket.objects.all():
            pprint.pprint(obj.key) #Usamos o pprint para uma saída mais amigável do resultado.
    except ClientError as e:
        print(e)

list_objects("hello-bucket-python")

E o resultado, conforme esperado, é o objeto recém criado:

Obter informações do objeto

Até agora fizemos upload e listamos todos os objetos do bucket. Agora vamos capturar informações de um objeto específico.

Edite o arquivo s3.py e substitua o conteúdo pelo seguinte:

import boto3
import pprint
from botocore.exceptions import ClientError

def view_object(bucket_name, object_name):
    try:
        s3_client = boto3.client('s3')
        response = s3_client.get_object(Bucket=bucket_name,Key=object_name)
                pprint.pprint(response) #Usamos o pprint para uma saída mais amigável do resultado.
    except ClientError as e:
        print(e)

view_object("hello-bucket-python", "exemplo.txt")

As principais informações do objeto exemplo.txt são exibidas:

Download do objeto

O próximo passo é fazer download do objeto.

Edite o arquivo s3.py e substitua o conteúdo pelo seguinte:

import boto3
from botocore.exceptions import ClientError

def download_object(bucket_name, keyname, download_name):
    try:
        s3 = boto3.client('s3')
        s3.download_file(bucket_name, keyname, download_name)
    except ClientError as e:
        print(e)

download_object("hello-bucket-python", "exemplo.txt", "exemplo_download.txt")

Ao executar, se nenhum erro for exibido, o arquivo foi baixado localmente.

Se você tentar fazer download de um objeto que não existe no bucket será retornado um erro 404.

Deletar objeto

A última operação de manipulação básica de objeto é a deleção.

Edite o arquivo s3.py e substitua o conteúdo pelo seguinte:

import boto3
from botocore.exceptions import ClientError

def delete_objects(bucket_name, keyname):
    try:
        s3_client = boto3.client('s3')
        response = s3_client.delete_object(Bucket=bucket_name,Key=keyname)
        print(response)
    except ClientError as e:
        print(e)

delete_objects("hello-bucket-python", "exemplo.txt")

Se nenhum erro for retornado, o objeto foi removido com sucesso:

Observe que nesse caso o valor de HTTPStatusCode foi 204. Está, correto, significa que o comando foi executado com sucesso, porém nenhum conteúdo foi retornado.

Se você executar o código para listar os objetos verá que está vazio.


Estes foram os comando básicos de manipulação de buckets e objetos do AWS S3. Existem dezenas de outras possibilidade, mas com este conteúdo você está pronto para começar.

Quer saber mais sobre Python? Confira mais conteúdos aqui no site da Coffops.

Deixe um comentário

O seu endereço de e-mail não será publicado.