รายการเนื้อหาของที่ฝากข้อมูลด้วย boto3


198

ฉันจะดูว่ามีอะไรอยู่ในกลุ่มใน S3 ด้วยได้boto3อย่างไร (เช่นทำ"ls")

ทำดังต่อไปนี้:

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

ผลตอบแทน:

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

ฉันจะดูเนื้อหาได้อย่างไร

คำตอบ:


243

วิธีหนึ่งในการดูเนื้อหาคือ:

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

1
ฉันสามารถดึงข้อมูลคีย์ภายใต้พา ธ เฉพาะในที่เก็บข้อมูลหรือด้วยตัวคั่นเฉพาะโดยใช้ boto3
ราหุลเคพี

109
คุณควรจะสามารถพูดได้mybucket.objects.filter(Prefix='foo/bar')และจะแสดงรายการวัตถุด้วยคำนำหน้านั้นเท่านั้น คุณสามารถส่งผ่านDelimiterพารามิเตอร์ได้
garnaat

3
ไม่ทำงานกับ boto3 AttributeError: 'S3' object ไม่มี attribute 'objects'
Shek

2
@garnaat ความคิดเห็นของคุณพูดถึงวิธีการกรองจริงๆช่วยฉัน (รหัสของฉันลงเอยง่ายและเร็วขึ้นมาก) - ขอบคุณ!
Edward Dixon

24
ผมจะแนะนำให้กับการใช้เป็นชื่อตัวแปรที่จะเงาชนิดทั่วโลกobject object
โอลิลันด์

100

นี้คล้ายกับ 'ls' แต่ไม่คำนึงถึงการประชุมโฟลเดอร์คำนำหน้าและจะแสดงรายการวัตถุในถัง มันเหลือผู้อ่านเพื่อกรองคำนำหน้าซึ่งเป็นส่วนหนึ่งของชื่อคีย์

ใน 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)

ใน 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
หากคุณต้องการใช้คำนำหน้าเช่นกันคุณสามารถทำได้เช่นนี้:conn.list_objects(Bucket='bucket_name', Prefix='prefix_string')['Contents']
markonovak

13
นี่แสดงรายการคีย์ 1,000 รายการแรกเท่านั้น จาก docstring: "ส่งคืนวัตถุบางส่วนหรือทั้งหมด (สูงสุด 1,000 รายการ) ในที่เก็บข้อมูล" นอกจากนี้ขอแนะนำให้คุณใช้ list_objects_v2 แทน list_objects (แม้ว่าสิ่งนี้จะส่งกลับเฉพาะ 1,000 คีย์แรกเท่านั้น)
Brett Widmeier

3
ข้อ จำกัด นี้ควรได้รับการจัดการโดยใช้ผู้ชำนาญการ
v25

44

ฉันสมมติว่าคุณได้กำหนดค่าการรับรองความถูกต้องแยกจากกัน

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

my_bucket = s3.Bucket('bucket_name')

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

30

หากคุณต้องการผ่านคีย์ ACCESS และ SECRET (ซึ่งคุณไม่ควรทำเพราะไม่ปลอดภัย):

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
ซึ่งปลอดภัยน้อยกว่าการมีไฟล์ข้อมูลรับรองที่ ~ / .aws / หนังสือรับรอง แม้ว่ามันจะเป็นทางออกที่ถูกต้อง
nu everest

6
สิ่งนี้จะต้องมีการมอบความลับในการควบคุมแหล่งที่มา ไม่ดี.
jan groth

2
คำตอบนี้ไม่ได้เพิ่มอะไรเลยเกี่ยวกับ API / กลไกการแสดงรายการวัตถุในขณะที่เพิ่มวิธีการพิสูจน์ตัวตนที่ไม่เกี่ยวข้องซึ่งเป็นเรื่องปกติสำหรับทรัพยากร boto ทั้งหมดและเป็นการรักษาความปลอดภัยที่ไม่ดี
Froyke

เพิ่มคำปฏิเสธในคำตอบเกี่ยวกับความปลอดภัย
rjurney

จะเกิดอะไรขึ้นถ้าคีย์ถูกจัดหาโดยระบบจัดการคีย์ / ความลับอย่าง Vault (Hashicorp) - นั่นจะไม่ดีไปกว่าการวางไฟล์ข้อมูลรับรองไว้ที่ ~ / .aws / หนังสือรับรอง?
SunnyAk

26

เพื่อจัดการรายการคีย์ขนาดใหญ่ (เช่นเมื่อรายการไดเรกทอรีมากกว่า 1,000 รายการ) ฉันใช้รหัสต่อไปนี้เพื่อสะสมค่าคีย์ (เช่นชื่อไฟล์) ด้วยหลายรายการ (ขอบคุณ Amelio ด้านบนสำหรับบรรทัดแรก) รหัสสำหรับ 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

ฟังก์ชั่นยูทิลิตี้s3keysของฉันนั้นเป็นคำตอบที่ดีที่สุดของ @ 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']

ในการทดสอบของฉัน (boto3 1.9.84) มันเร็วกว่าโค้ดเทียบเท่า (แต่ง่ายกว่า) อย่างมาก:

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 รับประกันผลการเรียงลำดับ UTF-8 ไบนารีที่start_afterเพิ่มประสิทธิภาพได้รับการเพิ่มฟังก์ชั่นเป็นครั้งแรก


นี่คือคำตอบที่ดีที่สุด ฉันเพิ่งแก้ไขคำตอบของ @ Hephaestus (เพราะมันสูงที่สุด) เมื่อฉันเลื่อนลง นี่ควรเป็นคำตอบที่ยอมรับและควรได้รับคะแนนพิเศษสำหรับการกระชับ ฉันจะเพิ่มที่กำเนิดจากรหัสที่สองจะต้องห่อในlist()เพื่อกลับรายการไฟล์
Richard D

@RichardD ผลลัพธ์ทั้งสองกำเนิดกลับมา ถังจำนวนมากที่ฉันตั้งเป้าหมายด้วยรหัสนี้มีคีย์มากกว่าหน่วยความจำของตัวเรียกใช้โค้ดที่สามารถจัดการได้ในครั้งเดียว (เช่น AWS Lambda) ฉันชอบที่จะบริโภคกุญแจเมื่อมันถูกสร้างขึ้น
Sean Summers

6

วิธีที่น่าติดตามมากกว่าการวนซ้ำผ่านลูปสำหรับลูปคุณสามารถพิมพ์วัตถุต้นฉบับที่มีไฟล์ทั้งหมดในที่เก็บ S3 ของคุณ:

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 คุณช่วยอธิบายหน่อยได้ไหมว่าทำไมคำตอบของฉันถึงแก้ไขเล็กน้อย - แทนที่ "a" ด้วยทุน "A" ในตอนต้นของคำตอบของฉันทำให้ชื่อเสียงของฉันเสื่อมลง -2 แต่ฉันคิดว่าทั้งคุณและฉันเห็นด้วย นั่นไม่เพียง แต่การแก้ไขของคุณจะไม่เกี่ยวข้องเลย แต่จริงๆแล้วค่อนข้างเล็กน้อยคุณจะไม่พูดอย่างนั้นเหรอ? โปรดมุ่งเน้นเนื้อหามากกว่าการแก้ไขแบบเด็ก ๆ ol'boy ที่จำเป็นที่สุด
Daniel Vieira

สิ่งเหล่านี้มีปฏิสัมพันธ์สองอย่างที่แตกต่างกัน 1. ฉันแก้ไขคำตอบของคุณซึ่งแนะนำแม้กระทั่งการสะกดผิดเล็กน้อย ฉันเห็นด้วยว่าขอบเขตระหว่างผู้เยาว์และเรื่องไร้สาระนั้นไม่ชัดเจน ฉันไม่ได้ลงคะแนนโพสต์ใด ๆ เพราะฉันเห็นข้อผิดพลาดและฉันไม่ได้ในกรณีนี้ ฉันเพียงแก้ไขข้อผิดพลาดทั้งหมดที่ฉันเห็น
petezurich

2. ฉันลงคะแนนคำตอบของคุณเพราะคุณเขียนว่าfiles_in_s3เป็น "รายการวัตถุ" ไม่มีสิ่งนั้นใน Python มันค่อนข้างจะทำซ้ำได้และฉันไม่สามารถทำให้โค้ดของคุณทำงานได้ดังนั้น downvoted กว่าที่ฉันพบข้อผิดพลาดและเห็นจุดของคุณ แต่ไม่สามารถเลิก downvote ของฉัน
petezurich

5
@ petezurich ไม่มีปัญหาเข้าใจจุดของคุณเพียงสิ่งเดียวใน Python list คือวัตถุเพราะทุกอย่างใน python นั้นเป็นวัตถุแล้วมันก็ตามมาด้วยว่า list นั้นเป็น iterable แต่อย่างแรกและสำคัญที่สุดคือ วัตถุ! นั่นคือเหตุผลที่ฉันไม่เข้าใจ downvote ของคุณคุณลงคะแนนบางอย่างที่ถูกต้องและรหัสที่ใช้งานได้ อย่างไรก็ตามขอขอบคุณสำหรับคำขอโทษและสิ่งที่ดีที่สุด
Daniel Vieira

1
@petezurich ทุกอย่างใน Python เป็นวัตถุ "วัตถุรายการ" เป็นที่ยอมรับอย่างสมบูรณ์
Zach Garwood

4

ObjectSummary:

มีตัวระบุสองตัวที่แนบมากับ ObjectSummary:

  • bucket_name
  • สำคัญ

boto3 S3: วัตถุสรุป

เพิ่มเติมเกี่ยวกับ Object Keys จากเอกสาร AWS S3:

คีย์วัตถุ:

เมื่อคุณสร้างวัตถุคุณระบุชื่อคีย์ซึ่งระบุวัตถุในที่เก็บข้อมูลโดยไม่ซ้ำกัน ตัวอย่างเช่นในคอนโซล Amazon S3 (ดูคอนโซลการจัดการ AWS) เมื่อคุณเน้นที่ฝากข้อมูลรายการของวัตถุในที่เก็บข้อมูลของคุณจะปรากฏขึ้น ชื่อเหล่านี้เป็นปุ่มวัตถุ ชื่อของคีย์คือลำดับของอักขระ Unicode ซึ่งการเข้ารหัส UTF-8 มีความยาวสูงสุด 1024 ไบต์

โมเดลข้อมูล Amazon S3 เป็นโครงสร้างแบบเรียบ: คุณสร้างที่เก็บข้อมูลและที่เก็บวัตถุ ไม่มีลำดับชั้นของ subbuckets หรือโฟลเดอร์ย่อย อย่างไรก็ตามคุณสามารถอนุมานลำดับชั้นแบบลอจิคัลโดยใช้ส่วนนำหน้าชื่อคีย์และตัวคั่นได้เช่นเดียวกับคอนโซล Amazon S3 คอนโซล Amazon S3 รองรับแนวคิดของโฟลเดอร์ สมมติว่าที่เก็บข้อมูลของคุณ (สร้างโดยผู้ดูแลระบบ) มีวัตถุสี่รายการที่มีคีย์วัตถุต่อไปนี้:

การพัฒนา / Projects1.xls

การเงิน / statement1.pdf

ส่วนตัว / taxdocument.pdf

s3-dg.pdf

อ้างอิง:

AWS S3: ปุ่มวัตถุ

นี่คือตัวอย่างโค้ดที่แสดงวิธีรับชื่อที่ฝากข้อมูลและคีย์วัตถุ

ตัวอย่าง:

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

ฉันเพิ่งทำเช่นนี้รวมถึงวิธีการตรวจสอบ:

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)

ทั้ง "get_s3_keys" คืนค่าคีย์สุดท้ายเท่านั้น
Alexey Vazhnov

รายการนี้ไฟล์ทั้งหมดในถัง แต่; lsคำถามคือวิธีการที่จะทำ คุณจะทำอย่างไร .. พิมพ์เฉพาะไฟล์ในรูท
Herman

1

ด้วยการปรับเปลี่ยนเล็กน้อยของรหัส @Hephaeastus ในหนึ่งในความคิดเห็นด้านบนเขียนวิธีการด้านล่างเพื่อแสดงรายการโฟลเดอร์และวัตถุ (ไฟล์) ในเส้นทางที่กำหนด ทำงานคล้ายกับคำสั่ง 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

รายการนี้ลงวัตถุ / โฟลเดอร์ทั้งหมดในเส้นทางที่กำหนด Folder_path สามารถปล่อยให้เป็น None โดยค่าเริ่มต้นและเมธอดจะแสดงรายการเนื้อหาทันทีของรูทของที่เก็บข้อมูล


0

นี่คือทางออก

นำเข้า boto3

s3 = boto3.resource ('s3')

BUCKET_NAME = 'ชื่อถัง S3 ของคุณเช่นที่ตั้งการลบ 11' '

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

สำหรับไฟล์ใน allFiles: print (file.key)


0

มันสามารถทำได้ดังนี้:

csv_files = s3.list_objects_v2(s3_bucket_path)
    for obj in csv_files['Contents']:
        key = obj['Key']

0

ดังนั้นคุณจึงขอเทียบเท่ากับaws s3 lsใน boto3 นี่จะเป็นการแสดงรายการโฟลเดอร์และไฟล์ระดับบนสุดทั้งหมด นี่คือสิ่งที่ฉันจะได้ใกล้ที่สุด จะแสดงเฉพาะโฟลเดอร์ระดับบนสุดทั้งหมด น่าแปลกใจที่การดำเนินงานอย่างง่ายเช่นนี้ยากเพียงใด

import boto3

def s3_ls():
  s3 = boto3.resource('s3')
  bucket = s3.Bucket('example-bucket')
  result = bucket.meta.client.list_objects(Bucket=bucket.name,
                                           Delimiter='/')
  for o in result.get('CommonPrefixes'):
    print(o.get('Prefix'))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.