如何使用Boto3下载S3存储桶的最新文件?

时间:2017-07-28 14:27:29

标签: python amazon-web-services amazon-s3 boto boto3

我能找到的其他问题是指旧版本的Boto。我想下载S3存储桶的最新文件。在documentation我发现有一个方法list_object_versions()可以获得一个布尔值IsLatest。不幸的是,我只设法建立连接并下载文件。你能告诉我如何扩展我的代码以获取存储桶的最新文件吗?谢谢

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

7 个答案:

答案 0 :(得分:7)

我提供的答案的变化:Boto3 S3, sort bucket by last modified。您可以修改代码以满足您的需求。

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]

答案 1 :(得分:2)

你可以

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

答案 2 :(得分:1)

在我使用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()

答案 3 :(得分:1)

当s3存储桶中有1000个以上的对象时,将进行处理。这基本上是@SaadK答案,没有for循环,并且对list_objects_v2使用较新的版本。

编辑:修复了发现的@Timothée-Jeannin问题。确保在所有页面上都标识为最新。

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Paginator.ListObjectsV2

import boto3

def get_most_recent_s3_object(bucket_name, prefix):
    s3 = boto3.client('s3')
    paginator = s3.get_paginator( "list_objects_v2" )
    page_iterator = paginator.paginate(Bucket=bucket_name, Prefix=prefix)
    latest = None
    for page in page_iterator:
        if "Contents" in page:
            latest2 = max(page['Contents'], key=lambda x: x['LastModified'])
            if latest is None or latest2['LastModified'] > latest['LastModified']:
                latest = latest2
    return latest

latest = get_most_recent_s3_object(bucket_name, prefix)

latest['Key']  # -->   'prefix/objectname'

答案 4 :(得分:0)

如果文件很多,则需要使用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]

答案 5 :(得分:0)

我还想从s3存储桶下载最新文件,但位于特定文件夹中。使用以下功能通过存储桶名称和前缀(即文件夹名称)获取最新的文件名。

function getConnectedComponents($relations,$total_nodes){
    $result = [];
    $nodes = [];
    $visited = [];

    for($i=1;$i<=$total_nodes;++$i){
        $nodes[$i] = [];
        $visited[$i] = false;
    }

    foreach($relations as $relation){
        $nodes[$relation[0]][] = $relation[1];
        $nodes[$relation[1]][] = $relation[0];
    }

    for($i=1;$i<=$total_nodes;++$i){
        if(!$visited[$i]){
            $temp = [];
            dfs($nodes,$i,$visited,$temp);
            $result[] = $temp;
        }
    }

    return $result;
}

function dfs($nodes,$node,&$visited,&$temp){
    if($visited[$node]) return;
    $visited[$node] = true;
    $temp[] = $node;
    foreach($nodes[$node] as $child_node){
        dfs($nodes,$child_node,$visited,$temp);
    }
}

答案 6 :(得分:-1)

您应该可以使用默认下载文件命令

下载最新版本的文件
   new_html = data['html']
   $selector = $('#id of block');
   $selector.html(new_html);

参考link

要获取上次修改或上传的文件,您可以使用以下

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中的答案,它不是最佳的,但它有效。