web-dev-qa-db-fra.com

Lire le contenu du fichier du compartiment S3 avec boto3

Je lis les noms de fichiers dans mon seau S3 en faisant

objs = boto3.client.list_objects(Bucket='my_bucket')
    while 'Contents' in objs.keys():
        objs_contents = objs['Contents']
        for i in range(len(objs_contents)):
            filename = objs_contents[i]['Key']

Maintenant, je dois obtenir le contenu réel du fichier, de la même manière qu'un open(filename).readlines(). Quel est le meilleur moyen?

32
mar tin

boto3 propose un modèle de ressource facilitant l'exécution de tâches telles que l'itération d'objets. Malheureusement, StreamingBody ne fournit pas readline ou readlines.

s3 = boto3.resource('s3')
bucket = s3.Bucket('test-bucket')
# Iterates through all the objects, doing the pagination for you. Each obj
# is an ObjectSummary, so it doesn't contain the body. You'll need to call
# get to get the whole body.
for obj in bucket.objects.all():
    key = obj.key
    body = obj.get()['Body'].read()
57
Jordon Phillips

Vous pourriez aussi considérer le smart_open module, qui supporte les itérateurs:

from smart_open import smart_open

# stream lines from an S3 object
for line in smart_open('s3://mybucket/mykey.txt', 'rb'):
    print(line.decode('utf8'))

et gestionnaires de contexte:

with smart_open('s3://mybucket/mykey.txt', 'rb') as s3_source:
    for line in s3_source:
         print(line.decode('utf8'))

    s3_source.seek(0)  # seek to the beginning
    b1000 = fin.read(1000)  # read 1000 bytes

Trouver smart_open à l'adresse https://pypi.org/project/smart_open/

10
caffreyd

Si vous souhaitez lire un fichier avec une configuration différente de celle par défaut, n'hésitez pas à utiliser directement mpu.aws.s3_read(s3path) ou le code copié-collé:

def s3_read(source, profile_name=None):
    """
    Read a file from an S3 source.

    Parameters
    ----------
    source : str
        Path starting with s3://, e.g. 's3://bucket-name/key/foo.bar'
    profile_name : str, optional
        AWS profile

    Returns
    -------
    content : bytes

    botocore.exceptions.NoCredentialsError
        Botocore is not able to find your credentials. Either specify
        profile_name or add the environment variables AWS_ACCESS_KEY_ID,
        AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN.
        See https://boto3.readthedocs.io/en/latest/guide/configuration.html
    """
    session = boto3.Session(profile_name=profile_name)
    s3 = session.client('s3')
    bucket_name, key = mpu.aws._s3_path_split(source)
    s3_object = s3.get_object(Bucket=bucket_name, Key=key)
    body = s3_object['Body']
    return body.read()
6
Martin Thoma