Ich habe mit boto3 gespielt, um zu lernen. Ich dachte, es wäre besser, die mit boto3 erhaltenen Ressourceninformationen in einer Datenklasse zu speichern und darauf zu verweisen (der Grund wird später beschrieben), also schreibe ich sie als Ergebnis.
Kurz gesagt, es ist ein SDK für die Arbeit mit AWS-Ressourcen in Python. Es ist in Low-Level-API (Client) und High-Level-API (Resorce) unterteilt. Es gibt endlose andere verwandte Artikel. Wenn Sie also mehr wissen möchten, lesen Sie sie bitte durch.
Dieses Mal werden wir die Low-Level-API verwenden.
Es bietet einen Dekorator, der dynamisch spezielle Methoden zuweist, die Klassen wie \ _ \ _ init \ _ \ _ () zugeordnet sind.
Eine Klasse mit dem folgenden Konstruktor
class Wanchan_Nekochan():
def __init__(self, cat:str, dog:str):
self.cat =cat
self.dog = dog
Ohne einen solchen Konstruktor können Sie intelligent schreiben.
@dataclass
class Wanchan_Nekochan():
cat: str
dog: str
https://docs.python.org/ja/3/library/dataclasses.html
Im Vergleich zu benannten Tupeln mit ähnlichen Funktionen gibt es die folgenden Unterschiede. -Namedtuple wird nach der Instanziierung unveränderlich (nicht bearbeitbar). Die Datenklasse ist standardmäßig veränderbar (bearbeitbar), aber wenn Sie das eingefrorene Argument als wahr übergeben Unveränderlich werden. ・ Datenklasse liest Daten etwas schneller (Überprüfung erforderlich)
Verwenden Sie dieses Mal die Methode list_buckets () der Klasse S3.Client, um die Bucket-Liste von S3 abzurufen. (Referenz) Offizielle Referenz https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.list_buckets
Die Definition der Antwort ist der folgende Wörterbuchtyp.
{
'Buckets': [
{
'Name': 'string',
'CreationDate': datetime
},
],
'Owner': {
'DisplayName': 'string',
'ID': 'string'
},
"ResponseMetadata": {
"RequestId": str,
"HTTPStatusCode": int,
"HTTPHeaders": dict,
"RetryAttempts": int
}
}
Wenn Sie Informationen aus der zurückgegebenen Antwort erhalten, wird der Schlüssel wie unten gezeigt als Zeichenfolge angegeben.
s3_client = session.client('s3')
data=s3_client.list_buckets()
status_code = data["ResponseMetadata"]["HTTPStatusCode"]
display_name = data["Owner"]["DisplayName"]
Da der Schlüssel durch eine Zeichenfolge angegeben wird, besteht die Gefahr von Rechtschreibfehlern, da die Funktion zur Vervollständigung der Eingabe durch die IDE nicht verwendet werden kann und es problematische Probleme gibt, z. B. nicht zu wissen, bis Sie sich auf den Typ der Daten beziehen.
Wenn Sie die Antwortdefinition im Voraus als Datenklasse definieren, ist ein Punktzugriff möglich, sodass die Eingabe abgeschlossen werden kann und Tipphinweise von mypy rigoros verwendet werden können.
Es gibt keinen Grund, keine Datenklasse zu verwenden !!!
Damit ...
from dataclasses import dataclass
from typing import List
from datetime import datetime
import boto3
from dacite import from_dict
session = boto3.session.Session(profile_name='s3_test')
#BasesClient befindet sich im globalen Bereich, um zu vermeiden, dass APIs mehrmals ausgelöst werden
#In Singleton implementieren
s3_client = session.client('s3')
@dataclass
class Boto3_Response():
RequestId: str
HostId: str
HTTPStatusCode: int
HTTPHeaders: Dict
RetryAttempts: int
@dataclass
class Inner_Owner():
DisplayName: str
ID: str
@dataclass
class Inner_Buckets():
Name: str
CreationDate: datetime
@dataclass
class S3_LIST():
ResponseMetadata: Boto3_Response
Owner: Inner_Owner
Buckets: List[Inner_Buckets]
@classmethod
def make_s3_name_list(cls):
return from_dict(data_class=cls, data=s3_client.list_buckets())
s3_list_response = S3_LIST.make_s3_name_list()
#Statuscode
print(s3_list_response.ResponseMetadata.HTTPStatusCode) #200
#Besitzername
print(s3_list_response.Owner.DisplayName) # nikujaga-kun
# ID
print(s3_list_response.Owner.ID)
#Eimerliste
print(*[bucket.Name for bucket in s3_list_response.Buckets])
from dacite import from_dict
Hier importieren wir eine Drittanbieter-Bibliothek namens Dacite. Dacite (ich habe es als "de" gelesen) ist einfach eine Bibliothek, mit der Wörterbuchtypen an verschachtelte Datenklassen übergeben und instanziiert werden können. https://pypi.org/project/dacite/
@dataclass
class Boto3_Response():
RequestId: str
HostId: str
HTTPStatusCode: int
HTTPHeaders: Dict
RetryAttempts: int
@dataclass
class Inner_Owner():
DisplayName: str
ID: str
@dataclass
class Inner_Buckets():
Name: str
CreationDate: datetime
@dataclass
class S3_LIST():
ResponseMetadata: Boto3_Response
Owner: Inner_Owner
Buckets: List[Inner_Buckets]
@classmethod
def make_s3_name_list(cls):
return from_dict(data_class=cls, data=s3_client.list_buckets())
In der obigen Definition von S3_LIST sind verschiedene Datenklassen Boto3_Response, Inner_Owner, Inner_Buckets als Attributtypen definiert. Wenn Sie die Antwort von list_buckets an S3_LIST übergeben, ohne from_dict of dacite zu verwenden
@classmethod
def make_s3_name_list(cls):
return cls(**s3_client.list_buckets())
Es sieht so aus, aber da es als Wörterbuchtyp anstelle einer Klasseninstanz übergeben wird, wird es wütend, wenn es kein solches Attribut gibt.
s3_list_response = S3_LIST.make_s3_name_list()
#Ärgern Sie sich hier über Attributfehler
print(s3_list_response.ResponseMetadata.HTTPStatusCode)
# 'dict' object has no attribute 'HTTPStatusCode'
Wenn Sie versuchen, hier etwas Gutes zu tun, indem Sie es einfach einbetten, wird es schwierig, wie es ist. Ich benutze Dacite als Bibliothek, die gute Arbeit leistet. Sie sollten unendlich auf der Schulter des Riesen reiten.
Datenklasse ist gut
Recommended Posts