Liệt kê nội dung của một thùng với boto3


198

Làm cách nào tôi có thể thấy những gì bên trong một thùng trong S3 với boto3? (tức là làm một"ls" )?

Làm như sau:

import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('some/path/')

trả về:

s3.Bucket(name='some/path/')

Làm thế nào để tôi thấy nội dung của nó?

Câu trả lời:


241

Một cách để xem nội dung sẽ là:

for my_bucket_object in my_bucket.objects.all():
    print(my_bucket_object)

1
Tôi có thể tìm nạp các khóa theo đường dẫn cụ thể trong nhóm hoặc với dấu phân cách cụ thể bằng boto3 không ??
Rahul KP

109
Bạn sẽ có thể nói mybucket.objects.filter(Prefix='foo/bar')và nó sẽ chỉ liệt kê các đối tượng có tiền tố đó. Bạn cũng có thể vượt qua một Delimitertham số.
garnaat

3
không hoạt động với boto3 AttributionError: đối tượng 'S3' không có thuộc tính 'đối tượng'
Shek

2
@garnaat Nhận xét của bạn đề cập đến phương pháp lọc đó thực sự giúp tôi (mã của tôi kết thúc đơn giản và nhanh hơn nhiều) - cảm ơn bạn!
Edward Dixon

24
Tôi sẽ khuyên không nên sử dụng objectnhư một tên biến vì nó sẽ phủ bóng kiểu toàn cầu object.
oliland

100

Điều này tương tự như 'ls' nhưng nó không tính đến quy ước thư mục tiền tố và sẽ liệt kê các đối tượng trong nhóm. Nó phụ thuộc vào người đọc để lọc các tiền tố là một phần của Tên khóa.

Trong Python 2:

from boto.s3.connection import S3Connection

conn = S3Connection() # assumes boto.cfg setup
bucket = conn.get_bucket('bucket_name')
for obj in bucket.get_all_keys():
    print(obj.key)

Trong Python 3:

from boto3 import client

conn = client('s3')  # again assumes boto.cfg setup, assume AWS S3
for key in conn.list_objects(Bucket='bucket_name')['Contents']:
    print(key['Key'])

39
Nếu bạn cũng muốn sử dụng tiền tố, bạn có thể làm như thế này:conn.list_objects(Bucket='bucket_name', Prefix='prefix_string')['Contents']
markonovak

13
Điều này chỉ liệt kê 1000 khóa đầu tiên. Từ chuỗi doc: "Trả về một số hoặc tất cả (tối đa 1000) đối tượng trong một thùng." Ngoài ra, bạn nên sử dụng list_objects_v2 thay vì list_objects (mặc dù, điều này cũng chỉ trả về 1000 khóa đầu tiên).
Brett Widmeier

3
Hạn chế này phải được xử lý bằng cách sử dụng Paginators
v25

44

Tôi giả sử bạn đã cấu hình xác thực riêng biệt.

import boto3
s3 = boto3.resource('s3')

my_bucket = s3.Bucket('bucket_name')

for file in my_bucket.objects.all():
    print(file.key)

30

Nếu bạn muốn vượt qua các khóa ACCESS và SECRET (điều mà bạn không nên làm, vì nó không an toàn):

from boto3.session import Session

ACCESS_KEY='your_access_key'
SECRET_KEY='your_secret_key'

session = Session(aws_access_key_id=ACCESS_KEY,
                  aws_secret_access_key=SECRET_KEY)
s3 = session.resource('s3')
your_bucket = s3.Bucket('your_bucket')

for s3_file in your_bucket.objects.all():
    print(s3_file.key)

13
Điều này kém an toàn hơn so với việc có tệp thông tin đăng nhập tại ~ / .aws / thông tin đăng nhập. Mặc dù nó là một giải pháp hợp lệ.
nu everest

6
Điều này sẽ yêu cầu cam kết bí mật để kiểm soát nguồn. Không tốt.
jan groth

2
Câu trả lời này không bổ sung gì về API / cơ học của các đối tượng liệt kê trong khi thêm phương thức xác thực không liên quan, phổ biến cho tất cả các tài nguyên boto và là một khôn ngoan bảo mật thực tiễn tồi
Froyke

Đã thêm từ chối trách nhiệm cho câu trả lời về bảo mật.
rjurney

Điều gì sẽ xảy ra nếu các khóa được cung cấp bởi hệ thống quản lý khóa / bí mật như Vault (Hashicorp) - sẽ không tốt hơn là chỉ đặt tệp thông tin xác thực ở ~ / .aws / thông tin đăng nhập?
SunnyAk

25

Để xử lý các danh sách khóa lớn (nghĩa là khi danh sách thư mục lớn hơn 1000 mục), tôi đã sử dụng đoạn mã sau để tích lũy các giá trị khóa (ví dụ tên tệp) với nhiều danh sách (nhờ Amelio ở trên cho các dòng đầu tiên). Mã dành cho python3:

    from boto3  import client
    bucket_name = "my_bucket"
    prefix      = "my_key/sub_key/lots_o_files"

    s3_conn   = client('s3')  # type: BaseClient  ## again assumes boto.cfg setup, assume AWS S3
    s3_result =  s3_conn.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter = "/")

    if 'Contents' not in s3_result:
        #print(s3_result)
        return []

    file_list = []
    for key in s3_result['Contents']:
        file_list.append(key['Key'])
    print(f"List count = {len(file_list)}")

    while s3_result['IsTruncated']:
        continuation_key = s3_result['NextContinuationToken']
        s3_result = s3_conn.list_objects_v2(Bucket=bucket_name, Prefix=prefix, Delimiter="/", ContinuationToken=continuation_key)
        for key in s3_result['Contents']:
            file_list.append(key['Key'])
        print(f"List count = {len(file_list)}")
    return file_list

20

Chức năng tiện ích s3keys của tôi về cơ bản là một phiên bản tối ưu hóa câu trả lời của @ Hephaestus:

import boto3


s3_paginator = boto3.client('s3').get_paginator('list_objects_v2')


def keys(bucket_name, prefix='/', delimiter='/', start_after=''):
    prefix = prefix[1:] if prefix.startswith(delimiter) else prefix
    start_after = (start_after or prefix) if prefix.endswith(delimiter) else start_after
    for page in s3_paginator.paginate(Bucket=bucket_name, Prefix=prefix, StartAfter=start_after):
        for content in page.get('Contents', ()):
            yield content['Key']

Trong các thử nghiệm của tôi (boto3 1.9.84), nó nhanh hơn đáng kể so với mã tương đương (nhưng đơn giản hơn):

import boto3


def keys(bucket_name, prefix='/', delimiter='/'):
    prefix = prefix[1:] if prefix.startswith(delimiter) else prefix
    bucket = boto3.resource('s3').Bucket(bucket_name)
    return (_.key for _ in bucket.objects.filter(Prefix=prefix))

S3 đảm bảo kết quả được sắp xếp nhị phân UTF-8 , start_aftertối ưu hóa đã được thêm vào chức năng đầu tiên.


Đây là câu trả lời tốt nhất. Tôi chỉ sửa đổi câu trả lời của @ Hephaestus (vì đó là mức cao nhất) khi tôi cuộn xuống. Đây phải là câu trả lời được chấp nhận và sẽ nhận được thêm điểm vì ngắn gọn. Tôi sẽ thêm rằng trình tạo từ mã thứ hai cần được bọc list()để trả về danh sách các tệp.
Richard D

@RichardD cả hai kết quả trả về máy phát điện. Nhiều nhóm tôi nhắm mục tiêu với mã này có nhiều khóa hơn bộ nhớ của người thực thi mã có thể xử lý cùng một lúc (ví dụ: AWS Lambda); Tôi thích tiêu thụ các khóa khi chúng được tạo ra.
Sean Summers

6

Một cách tinh vi hơn, thay vì lặp qua một vòng lặp for, bạn cũng có thể chỉ cần in đối tượng gốc có chứa tất cả các tệp trong nhóm S3 của mình:

session = Session(aws_access_key_id=aws_access_key_id,aws_secret_access_key=aws_secret_access_key)
s3 = session.resource('s3')
bucket = s3.Bucket('bucket_name')

files_in_s3 = bucket.objects.all() 
#you can print this iterable with print(list(files_in_s3))

3
@petezurich, bạn có thể vui lòng giải thích lý do tại sao một câu chỉnh sửa nhỏ nhặt như vậy cho câu trả lời của tôi không - thay thế một câu A bằng một chữ viết hoa khi bắt đầu câu trả lời của tôi làm giảm danh tiếng của tôi xuống -2, tuy nhiên tôi nghĩ cả bạn và tôi có thể đồng ý đó không chỉ là sự điều chỉnh của bạn KHÔNG liên quan, mà còn thực sự khá nhỏ nhặt, bạn sẽ không nói như vậy chứ? Vui lòng tập trung vào nội dung thay vì sửa đổi trẻ con, ol'boy bắt buộc nhất
Daniel Vieira

Đây là hai tương tác khác nhau. 1. Tôi đã chỉnh sửa câu trả lời của bạn được khuyến nghị ngay cả đối với các lỗi chính tả nhỏ. Tôi đồng ý, rằng ranh giới giữa nhỏ và tầm thường là mơ hồ. Tôi không downvote bất kỳ bài viết vì tôi thấy lỗi và tôi đã không trong trường hợp này. Tôi chỉ đơn giản là sửa tất cả các lỗi mà tôi thấy.
petezurich

2. Tôi đánh giá thấp câu trả lời của bạn vì bạn đã viết đó files_in_s3là một "đối tượng danh sách". Không có điều đó trong Python. Nó đúng hơn là một lần lặp và tôi không thể làm cho mã của bạn hoạt động và do đó bị hạ cấp. Hơn tôi đã tìm thấy lỗi và thấy quan điểm của bạn nhưng không thể hoàn tác được.
petezurich

5
@petezurich không có vấn đề gì cả vật! đó là lý do tại sao tôi không hiểu downvote của bạn - bạn đã bỏ phiếu một cái gì đó là chính xác và mã hoạt động. Dù sao, cảm ơn lời xin lỗi của bạn và tất cả những điều tốt đẹp nhất
Daniel Vieira

1
@petezurich Mọi thứ trong Python là một đối tượng. "Danh sách đối tượng" là hoàn toàn chấp nhận được.
Zach Garwood

4

Đối tượng:

Có hai mã định danh được đính kèm với ObjectSummary:

  • xô_name
  • Chìa khóa

boto3 S3: ObjectSummary

Thông tin thêm về Khóa đối tượng từ Tài liệu AWS S3:

Khóa đối tượng:

Khi bạn tạo một đối tượng, bạn chỉ định tên khóa, xác định duy nhất đối tượng trong nhóm. Ví dụ: trong bảng điều khiển Amazon S3 (xem Bảng điều khiển quản lý AWS), khi bạn tô sáng một nhóm, một danh sách các đối tượng trong nhóm của bạn xuất hiện. Những tên này là các khóa đối tượng. Tên của một khóa là một chuỗi các ký tự Unicode có mã hóa UTF-8 dài tối đa 1024 byte.

Mô hình dữ liệu Amazon S3 là một cấu trúc phẳng: bạn tạo một nhóm và nhóm lưu trữ các đối tượng. Không có hệ thống phân cấp của các nhóm con hoặc thư mục con; tuy nhiên, bạn có thể suy ra hệ thống phân cấp logic bằng cách sử dụng tiền tố và dấu phân cách tên khóa như bảng điều khiển Amazon S3 thực hiện. Bảng điều khiển Amazon S3 hỗ trợ khái niệm thư mục. Giả sử rằng nhóm của bạn (do quản trị viên tạo) có bốn đối tượng với các khóa đối tượng sau:

Phát triển / Dự án1.xls

Tài chính / sao kê1.pdf

Riêng tư / taxdocument.pdf

s3-dg.pdf

Tài liệu tham khảo:

AWS S3: Khóa đối tượng

Dưới đây là một số mã ví dụ minh họa cách lấy tên xô và khóa đối tượng.

Thí dụ:

import boto3
from pprint import pprint

def main():

    def enumerate_s3():
        s3 = boto3.resource('s3')
        for bucket in s3.buckets.all():
             print("Name: {}".format(bucket.name))
             print("Creation Date: {}".format(bucket.creation_date))
             for object in bucket.objects.all():
                 print("Object: {}".format(object))
                 print("Object bucket_name: {}".format(object.bucket_name))
                 print("Object key: {}".format(object.key))

    enumerate_s3()


if __name__ == '__main__':
    main()

3

Tôi chỉ làm như thế này, bao gồm cả phương thức xác thực:

s3_client = boto3.client(
                's3',
                aws_access_key_id='access_key',
                aws_secret_access_key='access_key_secret',
                config=boto3.session.Config(signature_version='s3v4'),
                region_name='region'
            )

response = s3_client.list_objects(Bucket='bucket_name', Prefix=key)
if ('Contents' in response):
    # Object / key exists!
    return True
else:
    # Object / key DOES NOT exist!
    return False

2
#To print all filenames in a bucket
import boto3

s3 = boto3.client('s3')

def get_s3_keys(bucket):

    """Get a list of keys in an S3 bucket."""
    resp = s3.list_objects_v2(Bucket=bucket)
    for obj in resp['Contents']:
      files = obj['Key']
    return files


filename = get_s3_keys('your_bucket_name')

print(filename)

#To print all filenames in a certain directory in a bucket
import boto3

s3 = boto3.client('s3')

def get_s3_keys(bucket, prefix):

    """Get a list of keys in an S3 bucket."""
    resp = s3.list_objects_v2(Bucket=bucket, Prefix=prefix)
    for obj in resp['Contents']:
      files = obj['Key']
      print(files)
    return files


filename = get_s3_keys('your_bucket_name', 'folder_name/sub_folder_name/')

print(filename)

Cả "get_s3_keys" chỉ trả về khóa cuối cùng.
Alexey Vazhnov

1

Với một chút sửa đổi mã của @Hephaeastus trong một trong những ý kiến ​​trên, đã viết phương pháp dưới đây để liệt kê các thư mục và đối tượng (tệp) trong một đường dẫn cụ thể. Hoạt động tương tự lệnh s3 ls.

from boto3 import session

def s3_ls(profile=None, bucket_name=None, folder_path=None):
    folders=[]
    files=[]
    result=dict()
    bucket_name = bucket_name
    prefix= folder_path
    session = boto3.Session(profile_name=profile)
    s3_conn   = session.client('s3')
    s3_result =  s3_conn.list_objects_v2(Bucket=bucket_name, Delimiter = "/", Prefix=prefix)
    if 'Contents' not in s3_result and 'CommonPrefixes' not in s3_result:
        return []

    if s3_result.get('CommonPrefixes'):
        for folder in s3_result['CommonPrefixes']:
            folders.append(folder.get('Prefix'))

    if s3_result.get('Contents'):
        for key in s3_result['Contents']:
            files.append(key['Key'])

    while s3_result['IsTruncated']:
        continuation_key = s3_result['NextContinuationToken']
        s3_result = s3_conn.list_objects_v2(Bucket=bucket_name, Delimiter="/", ContinuationToken=continuation_key, Prefix=prefix)
        if s3_result.get('CommonPrefixes'):
            for folder in s3_result['CommonPrefixes']:
                folders.append(folder.get('Prefix'))
        if s3_result.get('Contents'):
            for key in s3_result['Contents']:
                files.append(key['Key'])

    if folders:
        result['folders']=sorted(folders)
    if files:
        result['files']=sorted(files)
    return result

Điều này liệt kê tất cả các đối tượng / thư mục trong một đường dẫn nhất định. Thư mục_path có thể được để lại là Không theo mặc định và phương thức sẽ liệt kê các nội dung ngay lập tức của thư mục gốc.


0

Đây là giải pháp

nhập khẩu boto3

s3 = boto3.resource ('s3')

BucksET_NAME = 'Tên nhóm S3 của bạn, ví dụ như'deletemetesting11' '

allFiles = s3.Bucket (BucksET_NAME) .objects.all ()

cho tệp trong allFiles: print (file.key)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.