Ouvrez l'objet S3 en tant que chaîne avec Boto3

Réponses:

228

readrenverra des octets. Au moins pour Python 3, si vous souhaitez renvoyer une chaîne, vous devez décoder en utilisant le bon encodage:

import boto3

s3 = boto3.resource('s3')

obj = s3.Object(bucket, key)
obj.get()['Body'].read().decode('utf-8') 
Kamil Sindi
la source
1
pour que cette réponse fonctionne, je devais import botocoretel obj.get()['Body']<class 'botocore.response.StreamingBody'>
quel
1
@TzunghsingDavidWong, vous ne devriez pas avoir à importer un package pour appeler des méthodes sur un objet existant, non? Était-ce seulement nécessaire lors de l'expérimentation?
Ken Williams
1
quelle est la valeur de la clé dans l'obj = s3.Object (bucket, key) ** bucket is buckername ?? et la clé est le nom du fichier ??? *** s'il vous plaît corrigez-moi si je me trompe ...
Amaresh Jana
1
@Amaresh yes, bucket = bucket name and key = filename
Tipster
si une clé est au format pdf, est-ce que ça marche? ou s'il vous plaît suggérer un autre moyen utile, j'ai essayé d'import textract text = textract.process ('path / to / a.pdf', method = 'pdfminer') Cela sèmera une erreur d'importation
Arun Kumar
96

J'ai eu un problème pour lire / analyser l'objet à partir de S3 en raison de l' .get()utilisation de Python 2.7 dans un AWS Lambda.

J'ai ajouté json à l'exemple pour montrer qu'il est devenu parsable :)

import boto3
import json

s3 = boto3.client('s3')

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

NOTE (pour python 2.7): Mon objet est tout ascii, donc je n'ai pas besoin .decode('utf-8')

REMARQUE (pour python 3.6+): Nous sommes passés à python 3.6 et avons découvert que read()maintenant renvoie bytesdonc si vous voulez en extraire une chaîne, vous devez utiliser:

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

EvgenyKolyakov
la source
18
A travaillé pour moi! La documentation AWS Boto3 est un gâchis
Timo
76

Ce n'est pas dans la documentation de boto3. Cela a fonctionné pour moi:

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

objet étant un objet s3: http://boto3.readthedocs.org/en/latest/reference/services/s3.html#object

Gahl Levy
la source
1
en supposant que "Body" contient des données de chaîne, vous pouvez utiliser object.get () ["Body"]. read () pour convertir en une chaîne Python.
roehrijn
28
boto3 get terrible doc, à partir de 2016.
Andrew_1510
3
boto3.readthedocs.io/en/latest/reference/services/… nous indique que la valeur de retour est un dict, avec une clé "Body" de type StreamingBody, la recherche dans read the docs vous amène à botocore.readthedocs.io/ fr / latest / reference / response.html qui vous dira d'utiliser read ().
jeffrey
3
semble que maintenant get expected at least 1 arguments, got 0. Supprimez le get()et accédez directement à la propriété de l'objet "Body"
lurscher
14

Python3 + Utilisation de l'approche API boto3.

En utilisant l' API S3.Client.download_fileobj et l' objet de type fichier Python , le contenu de l'objet S3 peut être récupéré en mémoire.

Puisque le contenu récupéré est en octets, pour être converti en str , il doit être décodé.

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
la source
-5

Si le corps contient un io.StringIO, vous devez faire comme ci-dessous:

object.get()['Body'].getvalue()
Pyglouthon
la source