web-dev-qa-db-ja.com

Boto3を使用してS3バケットの最新ファイルをダウンロードする方法

私が見つけた他の質問は、古いバージョンのBotoに関するものでした。 S3バケットの最新ファイルをダウンロードしたいのですが。 documentation で、ブール値のIsLatestを取得するメソッドlist_object_versions()があることがわかりました。残念ながら、私は接続を確立してファイルをダウンロードすることに成功しました。バケットの最新ファイルを取得するためにコードを拡張する方法を教えてください。ありがとうございました

import boto3
conn = boto3.client('s3',
                    region_name="eu-west-1",
                    endpoint_url="customendpoint",
                    config=Config(signature_version="s3", s3={'addressing_style': 'path'}))

ここからは、mytestbucketというバケットから最新の追加ファイルを取得する方法がわかりません。バケットにはさまざまなcsvファイルがありますが、すべて異なる名前が付いています。

更新:

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]

これにより、次のエラーが発生します。

NameError: name 'get_last_modified' is not defined
6
jz22

私が提供した回答のバリエーション: Boto3 S3、バケットの最終更新日によるソート 。必要に応じてコードを変更できます。

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]

並べ替えを逆にしたい場合:

[obj['Key'] for obj in sorted(objs, key=get_last_modified, reverse=True)][0]
10
helloV

できるよ

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'])
7
smaraf

これは、私がやっているようにSessionを使用する場合のhelloVと基本的に同じ答えです。

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

objsをソートすると、最新のファイルを除くすべてのファイルをすばやく削除できます

for obj in objs[:-1]:
    s3.Object("my_bucket", obj.key).delete()
2
rpanai

ファイルがたくさんある場合は、helloVで言及されているようにページ付けを使用する必要があります。これは私がやった方法です。

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]
1
SaadK

デフォルトのファイルダウンロードコマンドを使用して、ファイルの最新バージョンをダウンロードできるはずです

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

参照 link

最後に変更またはアップロードされたファイルを取得するには、以下を使用できます

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]

このリファレンスの答え link は、最適ではないが機能することを示しています。

0
Ashan

また、s3バケットから最新のファイルをダウンロードしたいのですが、特定のフォルダーにあります。次の関数を使用して、バケット名とプレフィックス(フォルダ名)を使用して最新のファイル名を取得します。

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/')
0
Sayali Sonawane