Abra el objeto S3 como una cadena con Boto3

Respuestas:

228

readdevolverá bytes. Al menos para Python 3, si desea devolver una cadena, debe decodificar usando la codificación correcta:

import boto3

s3 = boto3.resource('s3')

obj = s3.Object(bucket, key)
obj.get()['Body'].read().decode('utf-8') 
Kamil Sindi
fuente
1
para que esta respuesta funcione, tuve que hacerlo import botocorecomo obj.get()['Body']es de tipo<class 'botocore.response.StreamingBody'>
Tzunghsing David Wong el
1
@TzunghsingDavidWong no debería tener que importar un paquete para llamar a métodos en un objeto existente, ¿verdad? ¿Tal vez eso solo era necesario mientras se experimentaba?
Ken Williams
1
¿Cuál es el valor de la clave en el obj = s3.Object (bucket, key) ** bucket is buckername ?? y la clave es el nombre del archivo ??? *** por favor
corrígeme
1
@Amaresh sí, cubo = nombre del cubo y clave = nombre de archivo
Tipster
si una clave es formato pdf, ¿funciona? o sugiera otra forma útil, intenté importar textract text = textract.process ('path / to / a.pdf', method = 'pdfminer') Sembrará un error de importación
Arun Kumar
96

Tuve un problema para leer / analizar el objeto desde S3 debido al .get()uso de Python 2.7 dentro de un AWS Lambda.

Agregué json al ejemplo para mostrar que se volvió analizable :)

import boto3
import json

s3 = boto3.client('s3')

obj = s3.get_object(Bucket=bucket, Key=key)
j = json.loads(obj['Body'].read())

NOTA (para python 2.7): mi objeto es todo ascii, por lo que no necesito .decode('utf-8')

NOTA (para Python 3.6+): Nos mudamos a Python 3.6 y descubrimos que read()ahora regresa, bytespor lo que si desea obtener una cadena, debe usar:

j = json.loads(obj['Body'].read().decode('utf-8'))

EvgenyKolyakov
fuente
18
¡Trabajó para mi! La documentación de AWS Boto3 es un desastre
Timo
76

Esto no está en la documentación de boto3. Esto funcionó para mí:

object.get()["Body"].read()

objeto siendo un objeto s3: http://boto3.readthedocs.org/en/latest/reference/services/s3.html#object

Gahl Levy
fuente
1
suponiendo que "Body" contiene datos de cadena, puede usar object.get () ["Body"]. read () para convertir a una cadena de Python.
roehrijn
28
boto3 obtiene un documento terrible, a partir de 2016.
Andrew_1510
3
boto3.readthedocs.io/en/latest/reference/services/... nos dice que el valor de retorno es un diccionario, con una llave "cuerpo" del tipo StreamingBody, en busca de que en leer los documentos se llega a botocore.readthedocs.io/ es / latest / reference / response.html que le indicará que use read ().
jeffrey
3
Parece que ahora get expected at least 1 arguments, got 0. Eliminar get()y acceder a la propiedad del objeto "Cuerpo" directamente
lurscher
13

Python3 + Usando el enfoque API de boto3.

Al usar la API S3.Client.download_fileobj y el objeto similar a un archivo Python , el contenido del Objeto S3 se puede recuperar en la memoria.

Dado que el contenido recuperado es bytes, para convertir a str , debe decodificarse.

import io
import boto3

client = boto3.client('s3')
bytes_buffer = io.BytesIO()
client.download_fileobj(Bucket=bucket_name, Key=object_key, Fileobj=bytes_buffer)
byte_value = bytes_buffer.getvalue()
str_value = byte_value.decode() #python3, default decoding is utf-8
Gatsby Lee
fuente
-5

Si el cuerpo contiene un io.StringIO, debe hacer lo siguiente:

object.get()['Body'].getvalue()
Pyglouthon
fuente