web-dev-qa-db-fra.com

Python boto, liste le contenu d'un répertoire spécifique dans le compartiment

J'ai un accès S3 uniquement à un répertoire spécifique dans un compartiment S3.

Par exemple, avec la commande s3cmd si j'essaie de lister tout le seau:

    $ s3cmd ls s3://my-bucket-url

J'ai une erreur: Access to bucket 'my-bucket-url' was denied

Mais si j'essaie d'accéder à un répertoire spécifique dans le compartiment, je peux voir le contenu:

    $ s3cmd ls s3://my-bucket-url/dir-in-bucket

Maintenant, je veux me connecter au compartiment S3 avec Python Boto. Similaire avec:

    bucket = conn.get_bucket('my-bucket-url')

J'ai une erreur: boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden

Mais si j'essaye:

    bucket = conn.get_bucket('my-bucket-url/dir-in-bucket')

Le script s’arrête pendant environ 10 secondes et affiche ensuite une erreur. Ci-dessous est la trace complète. Une idée de comment procéder avec cela?

Traceback (most recent call last):
  File "test_s3.py", line 7, in <module>
    bucket = conn.get_bucket('my-bucket-url/dir-name')
  File "/usr/local/lib/python2.7/dist-packages/boto/s3/connection.py", line 471, in get_bucket
    return self.head_bucket(bucket_name, headers=headers)
  File "/usr/local/lib/python2.7/dist-packages/boto/s3/connection.py", line 490, in head_bucket
    response = self.make_request('HEAD', bucket_name, headers=headers)
  File "/usr/local/lib/python2.7/dist-packages/boto/s3/connection.py", line 633, in make_request
    retry_handler=retry_handler
  File "/usr/local/lib/python2.7/dist-packages/boto/connection.py", line 1046, in make_request
    retry_handler=retry_handler)
  File "/usr/local/lib/python2.7/dist-packages/boto/connection.py", line 922, in _mexe
    request.body, request.headers)
  File "/usr/lib/python2.7/httplib.py", line 958, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python2.7/httplib.py", line 992, in _send_request
    self.endheaders(body)
  File "/usr/lib/python2.7/httplib.py", line 954, in endheaders
    self._send_output(message_body)
  File "/usr/lib/python2.7/httplib.py", line 814, in _send_output
    self.send(msg)
  File "/usr/lib/python2.7/httplib.py", line 776, in send
    self.connect()
  File "/usr/lib/python2.7/httplib.py", line 1157, in connect
    self.timeout, self.source_address)
  File "/usr/lib/python2.7/socket.py", line 553, in create_connection
    for res in getaddrinfo(Host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno -2] Name or service not known
13
Martin Taleski

Par défaut, lorsque vous effectuez un appel get_bucket dans boto, il essaie de valider que vous avez réellement accès à ce compartiment en effectuant une demande HEAD sur l'URL du compartiment. Dans ce cas, vous ne voulez pas que boto le fasse car vous n’avez pas accès au seau lui-même. Alors, fais ceci:

bucket = conn.get_bucket('my-bucket-url', validate=False)

et alors vous devriez pouvoir faire quelque chose comme ceci pour lister des objets:

for key in bucket.list(prefix='dir-in-bucket'): 
    <do something>

Si vous obtenez toujours un 403 Errror, essayez d’ajouter une barre oblique à la fin du préfixe.

for key in bucket.list(prefix='dir-in-bucket/'): 
    <do something>
22
garnaat

Pour boto3

import boto3

s3 = boto3.resource('s3')
my_bucket = s3.Bucket('my_bucket_name')

for object_summary in my_bucket.objects.filter(Prefix="dir_name/"):
    print object_summary.key
19
M.Vanderlee

Boto3 client:

import boto3

_BUCKET_NAME = 'mybucket'
_PREFIX = 'subfolder/'

client = boto3.client('s3', aws_access_key_id=ACCESS_KEY,
                            aws_secret_access_key=SECRET_KEY)

def ListFiles(client):
    """List files in specific S3 URL"""
    response = client.list_objects(Bucket=_BUCKET_NAME, Prefix=_PREFIX)
    for content in response.get('Contents', []):
        yield content.get('Key')

file_list = ListFiles(client)
for file in file_list:
    print 'File found: %s' % file

Utiliser la session

from boto3.session import Session

_BUCKET_NAME = 'mybucket'
_PREFIX = 'subfolder/'

session = Session(aws_access_key_id=ACCESS_KEY,
                  aws_secret_access_key=SECRET_KEY)

client = session.client('s3')

def ListFilesV1(client, bucket, prefix=''):
    """List files in specific S3 URL"""
    paginator = client.get_paginator('list_objects')
    for result in paginator.paginate(Bucket=bucket, Prefix=prefix,
                                     Delimiter='/'):
        for content in result.get('Contents', []):
            yield content.get('Key')

file_list = ListFilesV1(client, _BUCKET_NAME, prefix=_PREFIX)
for file in file_list:
    print 'File found: %s' % file
4
spicyramen

Si vous souhaitez répertorier tous les objets d'un dossier de votre compartiment, vous pouvez le spécifier lors de la liste.

import boto
conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = conn.get_bucket(AWS_BUCKET_NAME)
for file in bucket.list("FOLDER_NAME/", "/"):
    <do something with required file>
0
reetesh11