Otwórz obiekt S3 jako ciąg za pomocą Boto3

149

Zdaję sobie sprawę, że za pomocą Boto 2 można otworzyć obiekt S3 jako string z: get_contents_as_string()

Czy istnieje równoważna funkcja w boto3?

Gahl Levy
źródło
8
Miałem na myśli wybór ostatecznej odpowiedzi, najlepiej mojej;)
EvgenyKolyakov

Odpowiedzi:

228

readzwróci bajty. Przynajmniej dla Pythona 3, jeśli chcesz zwrócić ciąg, musisz zdekodować przy użyciu odpowiedniego kodowania:

import boto3

s3 = boto3.resource('s3')

obj = s3.Object(bucket, key)
obj.get()['Body'].read().decode('utf-8') 
Kamil Sindi
źródło
1
aby ta odpowiedź zadziałała, musiałem zrobić to, import botocoreco obj.get()['Body']jest typu<class 'botocore.response.StreamingBody'>
Tzunghsing David Wong
1
@TzunghsingDavidWong nie powinieneś musieć importować pakietu w celu wywołania metod na istniejącym obiekcie, prawda? Czy było to konieczne tylko podczas eksperymentowania?
Ken Williams
1
jaka jest wartość klucza w obj = s3.Object (bucket, key) ** bucket is buckername ?? a kluczem jest nazwa pliku ??? *** proszę poprawić mnie, jeśli się mylę ...
Amaresh Jana
1
@Amaresh tak, bucket = nazwa zasobnika i klucz = nazwa pliku
Tipster
jeśli klucz jest w formacie pdf, czy działa? lub zasugeruj inny przydatny sposób, próbowałem zaimportować tekst textract text = textract.process ('path / to / a.pdf', method = 'pdfminer') Spowoduje to błąd importu
Arun Kumar
96

Miałem problem z odczytaniem / parsowaniem obiektu z S3 z powodu .get()używania Pythona 2.7 wewnątrz AWS Lambda.

Dodałem json do przykładu, aby pokazać, że stał się parsowalny :)

import boto3
import json

s3 = boto3.client('s3')

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

UWAGA (dla Pythona 2.7): Mój obiekt to cały ascii, więc nie potrzebuję .decode('utf-8')

UWAGA (dla Pythona 3.6+): Przeszliśmy do Pythona 3.6 i odkryliśmy, że read()teraz zwraca, byteswięc jeśli chcesz uzyskać z niego ciąg, musisz użyć:

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

EvgenyKolyakov
źródło
18
Pracował dla mnie! Dokumentacja AWS Boto3 to bałagan
Timo
76

Tego nie ma w dokumentacji boto3. To zadziałało dla mnie:

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

obiekt będący obiektem s3: http://boto3.readthedocs.org/en/latest/reference/services/s3.html#object

Gahl Levy
źródło
1
zakładając, że "Body" zawiera dane typu string, możesz użyć object.get () ["Body"]. read (), aby przekonwertować na łańcuch w Pythonie.
roehrijn
28
boto3 otrzyma straszny dokument, od 2016 r.
Andrew_1510,
3
boto3.readthedocs.io/en/latest/reference/services/ ... mówi nam, że zwracana wartość to dict, z kluczem „Body” typu StreamingBody, szukanie tego w read the docs prowadzi do botocore.readthedocs.io/ en / latest / reference / response.html, który powie Ci, abyś użył read ().
jeffrey
3
wydaje się, że teraz get expected at least 1 arguments, got 0. Usuń get()i
uzyskaj
13

Python3 + Korzystanie z podejścia boto3 API.

Korzystając z interfejsu API S3.Client.download_fileobj i obiektu przypominającego plik w języku Python , zawartość obiektu S3 można pobrać do pamięci.

Ponieważ pobrana treść to bajty, aby przekonwertować ją na str , należy ją zdekodować.

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
źródło
-5

Jeśli body zawiera io.StringIO, musisz wykonać poniższe czynności:

object.get()['Body'].getvalue()
Pyglouthon
źródło