Как я могу увидеть, что внутри ведра в S3 с boto3
? (т.е. делать "ls"
)?
Делать следующее:
import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('some/path/')
возвращает:
s3.Bucket(name='some/path/')
Как я вижу его содержимое?
Как я могу увидеть, что внутри ведра в S3 с boto3
? (т.е. делать "ls"
)?
Делать следующее:
import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('some/path/')
возвращает:
s3.Bucket(name='some/path/')
Как я вижу его содержимое?
Ответы:
Один из способов просмотра содержимого:
for my_bucket_object in my_bucket.objects.all():
print(my_bucket_object)
mybucket.objects.filter(Prefix='foo/bar')
и он будет перечислять только объекты с этим префиксом. Вы также можете передать Delimiter
параметр.
object
в качестве имени переменной, поскольку она будет скрывать глобальный тип object
.
Это похоже на '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'])
conn.list_objects(Bucket='bucket_name', Prefix='prefix_string')['Contents']
Я предполагаю, что вы настроили аутентификацию отдельно.
import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket('bucket_name')
for file in my_bucket.objects.all():
print(file.key)
Если вы хотите передать ключи 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)
Чтобы обрабатывать большие списки ключей (например, когда список каталогов превышает 1000 элементов), я использовал следующий код для накопления значений ключей (т.е. имен файлов) с несколькими списками (спасибо Амелио выше за первые строки). Код для 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
Моя служебная функция 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
оптимизация была добавлена к первой функции.
list()
чтобы вернуть список файлов.
Более экономным способом, вместо того, чтобы перебирать цикл for, вы также можете просто напечатать исходный объект, содержащий все файлы внутри вашей корзины 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))
files_in_s3
это «объект списка». В Python такого нет. Скорее, это итеративный код, и я не смог заставить ваш код работать, и поэтому я отказался Тогда я обнаружил ошибку и понял вашу точку зрения, но не смог отменить мое понижение.
ObjectSummary:
Есть два идентификатора, которые прикреплены к ObjectSummary:
Подробнее об объектных ключах из документации AWS S3:
Ключи объекта:
Когда вы создаете объект, вы указываете имя ключа, которое однозначно идентифицирует объект в корзине. Например, в консоли Amazon S3 (см. Консоль управления AWS) при выделении сегмента отображается список объектов в нем. Эти имена являются ключами объекта. Имя для ключа представляет собой последовательность символов Unicode, кодировка UTF-8 которых имеет длину не более 1024 байтов.
Модель данных Amazon S3 представляет собой плоскую структуру: вы создаете контейнер, а контейнер хранит объекты. Нет иерархии вложенных или вложенных папок; однако вы можете вывести логическую иерархию, используя префиксы и разделители имен ключей, как это делает консоль Amazon S3. Консоль Amazon S3 поддерживает концепцию папок. Предположим, что ваше ведро (созданное администратором) имеет четыре объекта со следующими объектными ключами:
Разработка / Projects1.xls
Финансы / statement1.pdf
Частные лица / taxdocument.pdf
s3-dg.pdf
Ссылка:
Вот пример кода, который демонстрирует, как получить имя корзины и ключ объекта.
Пример:
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()
Я просто сделал это так, включая метод аутентификации:
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
#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)
ls
. Как бы ты это сделал .. только распечатай файлы в корне
С небольшим изменением кода @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 по умолчанию, и метод выведет список непосредственного содержимого корня сегмента.
импорт boto3
s3 = boto3.resource ('s3')
BUCKET_NAME = 'Ваше имя S3 Bucket, например,' deletemetesting11 ''
allFiles = s3.Bucket (BUCKET_NAME) .objects.all ()
для файла в allFiles: печать (file.key)
Итак, вы просите эквивалент 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'))
Вот простая функция, которая возвращает вам имена файлов всех файлов или файлов с определенными типами, такими как «json», «jpg».
def get_file_list_s3(bucket, prefix="", file_extension=None):
"""Return the list of all file paths (prefix + file name) with certain type or all
Parameters
----------
bucket: str
The name of the bucket. For example, if your bucket is "s3://my_bucket" then it should be "my_bucket"
prefix: str
The full path to the the 'folder' of the files (objects). For example, if your files are in
s3://my_bucket/recipes/deserts then it should be "recipes/deserts". Default : ""
file_extension: str
The type of the files. If you want all, just leave it None. If you only want "json" files then it
should be "json". Default: None
Return
------
file_names: list
The list of file names including the prefix
"""
import boto3
s3 = boto3.resource('s3')
my_bucket = s3.Bucket(bucket)
file_objs = my_bucket.objects.filter(Prefix=prefix).all()
file_names = [file_obj.key for file_obj in file_objs if file_extension is not None and file_obj.key.split(".")[-1] == file_extension]
return file_names