Les autres questions que j'ai pu trouver faisaient référence à une ancienne version de Boto. Je souhaite télécharger le dernier fichier d'un bucket S3. Dans le documentation j'ai trouvé qu'il y a une méthode list_object_versions () qui vous obtient un IsLatest booléen. Malheureusement, je n'ai réussi qu'à établir une connexion et à télécharger un fichier. Pourriez-vous s'il vous plaît me montrer comment je peux étendre mon code pour obtenir le dernier fichier du compartiment? Je vous remercie
import boto3
conn = boto3.client('s3',
region_name="eu-west-1",
endpoint_url="customendpoint",
config=Config(signature_version="s3", s3={'addressing_style': 'path'}))
De là, je ne sais pas comment obtenir le dernier fichier ajouté à partir d'un compartiment appelé mytestbucket
. Il y a plusieurs fichiers csv dans le bucket mais tous bien sûr avec un nom différent.
Mettre à jour:
import boto3
from botocore.client import Config
s3 = boto3.resource('s3', region_name="eu-west-1", endpoint_url="custom endpoint", aws_access_key_id = '1234', aws_secret_access_key = '1234', config=Config(signature_version="s3", s3={'addressing_style': 'path'}))
my_bucket = s3.Bucket('mytestbucket22')
unsorted = []
for file in my_bucket.objects.filter():
unsorted.append(file)
files = [obj.key for obj in sorted(unsorted, key=get_last_modified, reverse=True)][0:9]
Cela me donne l'erreur suivante:
NameError: name 'get_last_modified' is not defined
Variation de la réponse que j'ai fournie: Boto3 S3, trier le seau par dernière modification . Vous pouvez modifier le code en fonction de vos besoins.
get_last_modified = lambda obj: int(obj['LastModified'].strftime('%s'))
s3 = boto3.client('s3')
objs = s3.list_objects_v2(Bucket='my_bucket')['Contents']
last_added = [obj['Key'] for obj in sorted(objs, key=get_last_modified)][0]
Si vous souhaitez inverser le tri:
[obj['Key'] for obj in sorted(objs, key=get_last_modified, reverse=True)][0]
Tu peux faire
import boto3
s3_client = boto3.client('s3')
response = s3_client.list_objects_v2(Bucket='bucket_name', Prefix='prefix')
all = response['Contents']
latest = max(all, key=lambda x: x['LastModified'])
C'est fondamentalement la même réponse que helloV dans le cas où vous utilisez Session
comme je le fais.
from boto3.session import Session
import settings
session = Session(aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY)
s3 = session.resource("s3")
get_last_modified = lambda obj: int(obj.last_modified.strftime('%s'))
bckt = s3.Bucket("my_bucket")
objs = [obj for obj in bckt.objects.all()]
objs = [obj for obj in sorted(objs, key=get_last_modified)]
last_added = objs[-1].key
Le tri de objs
vous permet de supprimer rapidement tous les fichiers sauf le dernier avec
for obj in objs[:-1]:
s3.Object("my_bucket", obj.key).delete()
Si vous avez beaucoup de fichiers, vous devrez utiliser la pagination comme mentionné par helloV. Voilà comment je l'ai fait.
get_last_modified = lambda obj: int(obj['LastModified'].strftime('%s'))
s3 = boto3.client('s3')
paginator = s3.get_paginator( "list_objects" )
page_iterator = paginator.paginate( Bucket = "BucketName", Prefix = "Prefix")
for page in page_iterator:
if "Contents" in page:
last_added = [obj['Key'] for obj in sorted( page["Contents"], key=get_last_modified)][-1]
Vous devriez pouvoir télécharger la dernière version du fichier en utilisant la commande de téléchargement par défaut du fichier
import boto3
import botocore
BUCKET_NAME = 'mytestbucket'
KEY = 'fileinbucket.txt'
s3 = boto3.resource('s3')
try:
s3.Bucket(BUCKET_NAME).download_file(KEY, 'downloadname.txt')
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "404":
print("The object does not exist.")
else:
raise
Référence lien
Pour obtenir le dernier fichier modifié ou téléchargé, vous pouvez utiliser ce qui suit
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('myBucket')
unsorted = []
for file in my_bucket.objects.filter():
unsorted.append(file)
files = [obj.key for obj in sorted(unsorted, key=get_last_modified,
reverse=True)][0:9]
Comme réponse dans cette référence link déclare, ce n'est pas optimal mais cela fonctionne.
Je voulais également télécharger le dernier fichier du compartiment s3 mais situé dans un dossier spécifique. Utilisez la fonction suivante pour obtenir le dernier nom de fichier en utilisant le nom et le préfixe du compartiment (qui est le nom du dossier).
import boto3
def get_latest_file_name(bucket_name,prefix):
"""
Return the latest file name in an S3 bucket folder.
:param bucket: Name of the S3 bucket.
:param prefix: Only fetch keys that start with this prefix (folder name).
"""
s3_client = boto3.client('s3')
objs = s3_client.list_objects_v2(Bucket=bucket_name)['Contents']
shortlisted_files = dict()
for obj in objs:
key = obj['Key']
timestamp = obj['LastModified']
# if key starts with folder name retrieve that key
if key.startswith(prefix):
# Adding a new key value pair
shortlisted_files.update( {key : timestamp} )
latest_filename = max(shortlisted_files, key=shortlisted_files.get)
return latest_filename
latest_filename = get_latest_file_name(bucket_name='use_your_bucket_name',prefix = 'folder_name/')