python - example - Listado de contenidos de un cubo con boto3
python aws s3 example (9)
¿Cómo puedo ver qué hay dentro de un cubo en S3 con
boto3
?
(es decir, hacer un
"ls"
)?
Haciendo lo siguiente:
import boto3
s3 = boto3.resource(''s3'')
my_bucket = s3.Bucket(''some/path/'')
devoluciones:
s3.Bucket(name=''some/path/'')
¿Cómo veo su contenido?
Esto es similar a un ''ls'' pero no tiene en cuenta la convención de carpeta de prefijo y enumerará los objetos en el depósito. Le corresponde al lector filtrar los prefijos que forman parte del nombre de la clave.
En 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)
En 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''])
Mi
función de utilidad de
keys
s3
es esencialmente una versión optimizada de la respuesta de @ 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'']
En mis pruebas (boto3 1.9.84), es significativamente más rápido que el código equivalente (pero más simple):
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))
Como
S3 garantiza resultados ordenados binarios UTF-8
, se ha agregado una optimización
start_after
a la primera función.
Para manejar grandes listados de claves (es decir, cuando la lista del directorio es mayor a 1000 elementos), utilicé el siguiente código para acumular valores clave (es decir, nombres de archivos) con múltiples listados (gracias a Amelio anterior para las primeras líneas). El código es para 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
Si desea pasar las teclas ACCESO y SECRETO (que no debe hacer, porque no es seguro):
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)
Simplemente lo hice así, incluido el método de autenticación:
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
Supongo que ha configurado la autenticación por separado.
import boto3
s3 = boto3.resource(''s3'')
my_bucket = s3.Bucket(''bucket_name'')
for file in my_bucket.objects.all():
print(file.key)
Una forma de ver los contenidos sería:
for my_bucket_object in my_bucket.objects.all():
print(my_bucket_object)
Una forma más parsimoniosa, en lugar de iterar a través de un bucle for, también podría imprimir el objeto original que contiene todos los archivos dentro de su cubo 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))
ObjectSummary:
Hay dos identificadores que se adjuntan a ObjectSummary:
- nombre_cubeta
- llave
Más información sobre las claves de objeto de la documentación de AWS S3:
Claves de objeto:
Cuando crea un objeto, especifica el nombre de la clave, que identifica de forma exclusiva el objeto en el depósito. Por ejemplo, en la consola de Amazon S3 (consulte AWS Management Console), cuando resalta un depósito, aparece una lista de objetos en su depósito. Estos nombres son las claves de objeto. El nombre de una clave es una secuencia de caracteres Unicode cuya codificación UTF-8 tiene una longitud máxima de 1024 bytes.
El modelo de datos de Amazon S3 es una estructura plana: crea un depósito y el depósito almacena objetos. No hay jerarquía de subgrupos o subcarpetas; sin embargo, puede inferir la jerarquía lógica utilizando prefijos y delimitadores de nombres clave como lo hace la consola Amazon S3. La consola de Amazon S3 admite un concepto de carpetas. Suponga que su depósito (creado por el administrador) tiene cuatro objetos con las siguientes claves de objeto:
Desarrollo / Proyectos1.xls
Finanzas / estado de cuenta1.pdf
Private / taxdocument.pdf
s3-dg.pdf
Referencia:
Aquí hay un código de ejemplo que muestra cómo obtener el nombre del depósito y la clave del objeto.
Ejemplo:
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()