J'essaie de répertorier tous les répertoires d'un compartiment S3 en utilisant Python et Boto3.
J'utilise le code suivant:
s3 = session.resource('s3') # I already have a boto3 Session object
bucket_names = [
'this/bucket/',
'that/bucket/'
]
for name in bucket_names:
bucket = s3.Bucket(name)
for obj in bucket.objects.all(): # this raises an exception
# handle obj
Lorsque j'exécute cela, j'obtiens la trace de pile d'exceptions suivante:
File "botolist.py", line 67, in <module>
for obj in bucket.objects.all():
File "/Library/Python/2.7/site-packages/boto3/resources/collection.py", line 82, in __iter__
for page in self.pages():
File "/Library/Python/2.7/site-packages/boto3/resources/collection.py", line 165, in pages
for page in pages:
File "/Library/Python/2.7/site-packages/botocore/paginate.py", line 83, in __iter__
response = self._make_request(current_kwargs)
File "/Library/Python/2.7/site-packages/botocore/paginate.py", line 155, in _make_request
return self._method(**current_kwargs)
File "/Library/Python/2.7/site-packages/botocore/client.py", line 270, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/Library/Python/2.7/site-packages/botocore/client.py", line 335, in _make_api_call
raise ClientError(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (NoSuchKey) when calling the ListObjects operation: The specified key does not exist.
Quelle est la bonne façon de répertorier les répertoires dans un compartiment?
Merci d'avance...
Toutes ces autres réponses sont nulles. En utilisant
client.list_objects()
Vous limite à 1k résultats max. Les autres réponses sont fausses ou trop complexes.
Traiter le jeton de continuation vous-même est une idée terrible. Utilisez simplement paginator, qui traite de cette logique pour vous
La solution que vous recherchez est:
[e['Key'] for p in client.get_paginator("list_objects_v2")\
.paginate(Bucket='my_bucket')
for e in p['Contents']]
Si vous avez la session, créez un client et obtenez le CommonPrefixes
des clients list_objects
:
client = session.client('s3',
# region_name='eu-west-1'
)
result = client.list_objects(Bucket='MyBucket', Delimiter='/')
for obj in result.get('CommonPrefixes'):
#handle obj.get('Prefix')
Il pourrait y avoir beaucoup de dossiers et vous voudrez peut-être commencer dans un sous-dossier. Quelque chose comme ça pourrait gérer cela:
def folders(client, bucket, prefix=''):
paginator = client.get_paginator('list_objects')
for result in paginator.paginate(Bucket=bucket, Prefix=prefix, Delimiter='/'):
for prefix in result.get('CommonPrefixes', []):
yield prefix.get('Prefix')
gen_folders = folders(client, 'MyBucket')
list(gen_folders)
gen_subfolders = folders(client, 'MyBucket', prefix='MySubFolder/')
list(gen_subfolders)
Vous pouvez également utiliser boto3.client
Exemple
>>> import boto3
>>> client = boto3.client('s3')
>>> client.list_objects(Bucket='MyBucket')
list_objects
prend également en charge d'autres arguments qui peuvent être nécessaires pour itérer le résultat: Bucket, Delimiter, EncodingType, Marker, MaxKeys, Prefix
La meilleure façon d'obtenir la liste de TOUS les objets avec un préfixe spécifique dans un compartiment S3 est d'utiliser list_objects_v2
avec ContinuationToken
pour dépasser la limite de pagination de 1 000 objets.
import boto3
s3 = boto3.client('s3')
s3_bucket = 'your-bucket'
s3_prefix = 'your/prefix'
partial_list = s3.list_objects_v2(
Bucket=s3_bucket,
Prefix=s3_prefix)
obj_list = partial_list['Contents']
while partial_list['IsTruncated']:
next_token = partial_list['NextContinuationToken']
partial_list = s3.list_objects_v2(
Bucket=s3_bucket,
Prefix=s3_prefix,
ContinuationToken=next_token)
obj_list.extend(partial_list['Contents'])
J'aurais pensé que vous ne pouvez pas avoir de barre oblique dans le nom d'un seau. Vous dites que vous souhaitez répertorier tous les répertoires dans un compartiment, mais votre code tente de répertorier tout le contenu (pas nécessairement les répertoires) dans un certain nombre de compartiments. Ces seaux n'existent probablement pas (car ils ont des noms illégaux). Alors quand tu cours
bucket = s3.Bucket(name)
le compartiment est probablement nul et la liste suivante échouera.