como excluir arquivos do balde Amazon S3?

92

Eu preciso escrever um código em python que excluirá o arquivo necessário de um balde do Amazon s3. Consigo me conectar ao bucket do Amazon s3 e também salvar arquivos, mas como posso excluir um arquivo?

Suhail
fonte
Qual biblioteca Python (se houver) você está usando para suporte S3? Ou você está indo direto para as interfaces REST ou SOAP em seu código Python?
TJ Crowder
1
estou usando a biblioteca python boto.s3
Suhail

Respostas:

98

Usando boto3(atualmente versão 1.4.4) use S3.Object.delete().

import boto3

s3 = boto3.resource('s3')
s3.Object('your-bucket', 'your-key').delete()
Kohányi Róbert
fonte
1
Se o objeto não estiver presente, ele gerará um erro?
Akash Tantri de
3
@AkashTantri Eu não tentei pessoalmente, mas o documento diz que remove a versão nula (se houver) [...] Se não houver uma versão nula, o Amazon S3 não remove nenhum objeto. Portanto, meu palpite é que não haverá um erro. Se acontecer de você tentar (basta fazer algo parecido s3.Object('existing-bucket', 'bogus-key').delete()e ver o que acontece. Tente também s3.Object('bogus-bucket', 'bogus-key').delete().
Kohányi Róbert
1
Funciona perfeitamente, esse é o verdadeiro poder do python
yunus
@yunus este é um comentário sério?
Henry Henrinson
O your-keyaqui significa o nome do arquivo real your-bucketno S3?
Underoos
91

descobri mais uma maneira de fazer isso usando o boto:

from boto.s3.connection import S3Connection, Bucket, Key

conn = S3Connection(AWS_ACCESS_KEY, AWS_SECERET_KEY)

b = Bucket(conn, S3_BUCKET_NAME)

k = Key(b)

k.key = 'images/my-images/'+filename

b.delete_key(k)
Suhail
fonte
10
Se você quiser excluir TUDO em um intervalo, pode fazer:for x in b.list(): b.delete_key(x.key)
jontsai
19
Eu amo como em meu arquivo parece serbucket.list()
Artur Sapek
Para que este trecho de código funcione conforme apresentado, você precisará importar Buckete Keytambém. Como em:from boto.s3.connection import S3Connection, Bucket, Key
Nick Chammas
Eu recebo, >>> from boto.s3.connection import S3Connection, Bucket, Key Traceback (most recent call last): File "<console>", line 1, in <module> ImportError: No module named boto.s3.connectionpor favor, atualize a resposta para boto3
Harry Moreno
1
descobri e redigiu uma solução harrymoreno.com/2017/04/24/…
Harry Moreno
76

Usando o Python boto3 SDK (e supondo que as credenciais sejam configuradas para AWS), o seguinte excluirá um objeto especificado em um intervalo:

import boto3

client = boto3.client('s3')
client.delete_object(Bucket='mybucketname', Key='myfile.whatever')
Anconia
fonte
6
@Rob A documentação do boto3 é enganosa. ele criará um marcador de exclusão se o objeto for versionado. Caso contrário, ele excluirá o objeto.
jarmod
1
Limpo e simples. Pode ser a resposta aceita e definitivamente deve ser combinada com a resposta de @Kohányi Róbert, pois ambas são as melhores abordagens para a tarefa.
PaulB
16

Bem-vindo a 2020, aqui está a resposta em Python / Django:

from django.conf import settings 
import boto3   
s3 = boto3.client('s3')
s3.delete_object(Bucket=settings.AWS_STORAGE_BUCKET_NAME, Key=f"media/{item.file.name}")

Levei muito tempo para encontrar a resposta e era tão simples quanto isso.

Comm4nd0
fonte
4

Estou surpreso que não seja esta maneira fácil key.delete()::

from boto.s3.connection import S3Connection, Bucket, Key

conn = S3Connection(AWS_ACCESS_KEY, AWS_SECERET_KEY)
bucket = Bucket(conn, S3_BUCKET_NAME)
k = Key(bucket = bucket, name=path_to_file)
k.delete()
Cyril N.
fonte
4

Tente procurar um método atualizado , pois Boto3 pode mudar de tempos em tempos. Eu usei my_bucket.delete_objects () :

import boto3
from boto3.session import Session

session = Session(aws_access_key_id='your_key_id',
                  aws_secret_access_key='your_secret_key')

# s3_client = session.client('s3')
s3_resource = session.resource('s3')
my_bucket = s3_resource.Bucket("your_bucket_name")

response = my_bucket.delete_objects(
    Delete={
        'Objects': [
            {
                'Key': "your_file_name_key"   # the_name of_your_file
            }
        ]
    }
)

Javi
fonte
3

Por meio de qual interface? Usando a interface REST, basta enviar uma exclusão :

DELETE /ObjectName HTTP/1.1
Host: BucketName.s3.amazonaws.com
Date: date
Content-Length: length
Authorization: signatureValue

Via interface SOAP :

<DeleteObject xmlns="http://doc.s3.amazonaws.com/2006-03-01">
  <Bucket>quotes</Bucket>
  <Key>Nelson</Key>
  <AWSAccessKeyId> 1D9FVRAYCP1VJEXAMPLE=</AWSAccessKeyId>
  <Timestamp>2006-03-01T12:00:00.183Z</Timestamp>
  <Signature>Iuyz3d3P0aTou39dzbqaEXAMPLE=</Signature>
</DeleteObject>

Se você estiver usando uma biblioteca Python como boto , deve expor um recurso de "exclusão", como delete_key().

TJ Crowder
fonte
sim, estou usando aquela biblioteca python, mas isso excluirá o arquivo? devo fazer desta forma: k.key = 'images / anon-images / small /' + nome do arquivo k.delete_key () correto? Por favor deixe-me saber.
Suhail
@Suhail: Eu não usei essa biblioteca, mas da fonte que vinculei, o que ela realmente está fazendo é uma DELETEchamada por meio da interface REST. Então sim, apesar do nome "delete_key" (que eu concordo não estar claro), ele está realmente excluindo o objeto referenciado pela chave.
TJ Crowder
1
Que tal remover muitos arquivos com um prefixo comum no nome? O S3 permite alguma exclusão em massa para esse caso, ou excluí-los um por um (o que é lento) é a obrigação?
Illarion Kovalchuk
@Shaman: Não sou um especialista em S3, mas, pelo que sei , você só pode excluir um arquivo específico. Mas você provavelmente quer fazer isso como uma pergunta para chamar a atenção dos especialistas do S3.
TJ Crowder
Logo após comentar aqui eu adicionei essa pergunta. Tem 2 visualizações ainda :)
Illarion Kovalchuk
2

A maneira mais simples de fazer isso é:

import boto3
s3 = boto3.resource("s3")
bucket_source = {
            'Bucket': "my-bcuket",
            'Key': "file_path_in_bucket"
        }
s3.meta.client.delete(bucket_source)
KayV
fonte
2

por favor tente este código

import boto3   
s3 = boto3.client('s3')
s3.delete_object(Bucket="s3bucketname", Key="s3filepath")
Santosh Kumar Manda
fonte
1

Por enquanto, resolvi o problema usando o utilitário s3cmd do Linux . Usei assim no Python:

delFile = 's3cmd -c /home/project/.s3cfg del s3://images/anon-images/small/' + filename
os.system(delFile)
Suhail
fonte
1
Não é exatamente pythônico invocar um subshell para se comunicar com o S3 (uma biblioteca ou uma transação HTTP direta seria mais elegante), mas ainda funciona. Não acho que mereça um voto negativo. +1.
Randall Cook de
1

Tem funcionado para mim, tente.

import boto
import sys
from boto.s3.key import Key
import boto.s3.connection

AWS_ACCESS_KEY_ID = '<access_key>'
AWS_SECRET_ACCESS_KEY = '<secret_access_key>'
Bucketname = 'bucket_name' 

conn = boto.s3.connect_to_region('us-east-2',
        aws_access_key_id=AWS_ACCESS_KEY_ID,
        aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
        is_secure=True,              
        calling_format = boto.s3.connection.OrdinaryCallingFormat(),
        )
bucket = conn.get_bucket(Bucketname)

k = Key(bucket)

k.key = 'filename to delete'
bucket.delete_key(k)   
muthu
fonte
1

você pode fazer isso usando aws cli: https://aws.amazon.com/cli/ e algum comando unix.

este comando aws cli deve funcionar:

aws s3 rm s3://<your_bucket_name> --exclude "*" --include "<your_regex>" 

se você quiser incluir subpastas você deve adicionar a opção --recursive

ou com comandos unix:

aws s3 ls s3://<your_bucket_name>/ | awk '{print $4}' | xargs -I%  <your_os_shell>   -c 'aws s3 rm s3:// <your_bucket_name>  /% $1'

explicação:

  1. liste todos os arquivos no balde --pipe ->
  2. obtenha o 4º parâmetro (é o nome do arquivo) --pipe -> // você pode substituí-lo pelo comando linux para corresponder ao seu padrão
  3. execute delete script com aws cli
ggcarmi
fonte
1

se você está tentando deletar o arquivo usando seu próprio console host local então você pode tentar rodar este script python assumindo que você já atribuiu seu id de acesso e chave secreta no sistema

import boto3

#my custom sesssion
aws_m=boto3.session.Session(profile_name="your-profile-name-on-local-host")
client=aws_m.client('s3')

#list bucket objects before deleting 
response = client.list_objects(
    Bucket='your-bucket-name'
)
for x in response.get("Contents", None):
    print(x.get("Key",None));

#delete bucket objects
response = client.delete_object(
    Bucket='your-bucket-name',
    Key='mydocs.txt'
)

#list bucket objects after deleting
response = client.list_objects(
    Bucket='your-bucket-name'
)
for x in response.get("Contents", None):
    print(x.get("Key",None));
Utkarsh Mehta
fonte
0

O seguinte funcionou para mim (com base no exemplo de um modelo Django, mas você pode usar o código do deletemétodo sozinho).

import boto3
from boto3.session import Session
from django.conf import settings

class Video(models.Model):
    title=models.CharField(max_length=500)
    description=models.TextField(default="")
    creation_date=models.DateTimeField(default=timezone.now)
    videofile=models.FileField(upload_to='videos/', null=True, verbose_name="")
    tags = TaggableManager()

    actions = ['delete']

    def __str__(self):
        return self.title + ": " + str(self.videofile)

    def delete(self, *args, **kwargs):
        session = Session (settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
        s3_resource = session.resource('s3')
        s3_bucket = s3_resource.Bucket(settings.AWS_STORAGE_BUCKET_NAME)

        file_path = "media/" + str(self.videofile)
        response = s3_bucket.delete_objects(
            Delete={
                'Objects': [
                    {
                        'Key': file_path
                    }
                ]
            })
        super(Video, self).delete(*args, **kwargs)
MadPhysicist
fonte
0

Abaixo está um snippet de código que você pode usar para excluir o intervalo,

import boto3, botocore
from botocore.exceptions import ClientError

s3 = boto3.resource("s3",aws_access_key_id='Your-Access-Key',aws_secret_access_key='Your-Secret-Key')
s3.Object('Bucket-Name', 'file-name as key').delete()
Ganesan J
fonte