Różnica w boto3 między zasobem, klientem i sesją?

Odpowiedzi:

248

Oto kilka bardziej szczegółowych informacji o tym, o co chodzi w kliencie , zasobach i sesji .

Klient:

  • dostęp do usługi AWS niskiego poziomu
  • wygenerowany z opisu usługi AWS
  • udostępnia klienta botocore twórcy
  • zwykle odwzorowuje 1: 1 z interfejsem API usługi AWS
  • wszystkie operacje usługi AWS są obsługiwane przez klientów
  • nazwy metod wężowych (np. ListBuckets API => list_buckets method)

Oto przykład dostępu na poziomie klienta do obiektów segmentu S3 (maksymalnie 1000 **):

import boto3

client = boto3.client('s3')
response = client.list_objects_v2(Bucket='mybucket')
for content in response['Contents']:
    obj_dict = client.get_object(Bucket='mybucket', Key=content['Key'])
    print(content['Key'], obj_dict['LastModified'])

** musisz użyć paginatora lub zaimplementować własną pętlę, wywołując wielokrotnie list_objects () ze znacznikiem kontynuacji, jeśli jest ich więcej niż 1000.

Ratunek:

  • obiektowy interfejs API wyższego poziomu
  • wygenerowane z opisu zasobu
  • używa identyfikatorów i atrybutów
  • ma działania (operacje na zasobach)
  • udostępnia zasoby podrzędne i zbiory zasobów AWS
  • nie zapewnia 100% pokrycia API usług AWS

Oto równoważny przykład z dostępem na poziomie zasobów do obiektów segmentu S3 (wszystkie):

import boto3

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
for obj in bucket.objects.all():
    print(obj.key, obj.last_modified)

Zauważ, że w tym przypadku nie musisz wykonywać drugiego wywołania API, aby uzyskać obiekty; są dostępne jako kolekcja na wiadrze. Te zbiory zasobów podrzędnych są leniwie załadowane.

Widać, że Resourcewersja kodu jest znacznie prostsza, bardziej zwarta i ma większe możliwości (wykonuje podział na strony). ClientWersja kodu faktycznie być bardziej skomplikowane niż przedstawiono powyżej, jeśli chciał to paginacji.

Sesja:

  • przechowuje informacje o konfiguracji (przede wszystkim poświadczenia i wybrany region)
  • umożliwia tworzenie klientów usług i zasobów
  • W razie potrzeby boto3 tworzy dla ciebie domyślną sesję

Przydatnym źródłem informacji o tych koncepcjach boto3 jest wideo wprowadzające: Invent .

jarmod
źródło
2
Czy jest jakaś różnica w wydajności między klientem a zasobem? Miałem ten problem, gdy usuwanie wiadomości z kolejki sqs było szybsze przy użyciu klienta i wolniejsze przy użyciu zasobów.
Vaulstein,
3
@Vaulstein Nie mam żadnych szczegółowych porównań do udostępnienia, ale ogólnie oczekiwałbym, że interfejsy klienta będą lżejsze niż zasoby, a zatem potencjalnie szybsze w czasie wykonywania (choć wolniej kodują).
jarmod
@ jarmod W ramach nauki próbowałem utworzyć segment S3 przy użyciu obu metod. Wydaje mi się, że tworzenie zasobów odbywa się szybciej, gdy używa się „Klienta” w porównaniu z „Zasobem”. Czy to jest poprawne? Jeśli tak, dlaczego tworzenie zasobów jest szybsze w kliencie?
Saravanan G
1
@ SaravananG Jeśli możesz s3.set_stream_logger('botocore'), możesz zobaczyć logi metaprogramowania, które boto3 (wzywając do botocore) robi pod maską. Działa, więc nie musisz. Ma cały system zdarzeń do dostosowywania / podłączania i głęboką taksonomię zdarzeń (3?) Do obsługi przygotowywania żądań, analizy odpowiedzi i łączenia zależnych połączeń. Na uwagę zasługuje budowanie parametrów, podpisywanie wniosków, wykrywanie regionu. Dla twojej informacji modyfikowanie to magiczny ból. Zobacz łatwą zmianę .
mcint,
89

Spróbuję wyjaśnić to tak prosto, jak to możliwe. Dlatego nie ma gwarancji dokładności rzeczywistych warunków.

Sesja jest miejscem, w którym można nawiązać połączenie z usługami AWS. Np. Następująca jest domyślna sesja, która korzysta z domyślnego profilu poświadczeń (np. ~ / .Aws / credentials, lub załóż EC2 za pomocą profilu wystąpienia IAM)

sqs = boto3.client('sqs')
s3 = boto3.resource('s3')

Ponieważ sesja domyślna jest ograniczona do użytego profilu lub profilu instancji, czasami trzeba użyć sesji niestandardowej, aby zastąpić domyślną konfigurację sesji (np. Nazwa_ regionu, adres_początkowy itp.) Np.

# custom resource session must use boto3.Session to do the override
my_west_session = boto3.Session(region_name = 'us-west-2')
my_east_session = boto3.Session(region_name = 'us-east-1')
backup_s3 = my_west_session.resource('s3')
video_s3 = my_east_session.resource('s3')

# you have two choices of create custom client session. 
backup_s3c = my_west_session.client('s3')
video_s3c = boto3.client("s3", region_name = 'us-east-1')

Zasób : zalecana do użycia klasa usług wysokiego poziomu. Pozwala to na powiązanie określonych zasobów AWS i przekazywanie ich dalej, więc po prostu korzystasz z tej abstrakcji, nie martwiąc się o to, które usługi docelowe są wskazywane. Jak zauważyłeś z części sesji, jeśli masz sesję niestandardową, po prostu przekazujesz ten obiekt abstrakcyjny, niż martwisz się o wszystkie niestandardowe regiony itp. Poniżej znajduje się skomplikowany przykład np

import boto3 
my_west_session = boto3.Session(region_name = 'us-west-2')
my_east_session = boto3.Session(region_name = 'us-east-1')
backup_s3 = my_west_session.resource("s3")
video_s3 = my_east_session.resource("s3")
backup_bucket = backup_s3.Bucket('backupbucket') 
video_bucket = video_s3.Bucket('videobucket')

# just pass the instantiated bucket object
def list_bucket_contents(bucket):
   for object in bucket.objects.all():
      print(object.key)

list_bucket_contents(backup_bucket)
list_bucket_contents(video_bucket)

Klient jest obiektem klasy niskiego poziomu. Dla każdego połączenia z klientem należy jawnie określić zasoby kierowania, nazwa docelowej usługi musi być długa. Utracisz zdolność abstrakcji.

Na przykład, jeśli zajmujesz się tylko sesją domyślną, wygląda to podobnie do boto3.resource.

import boto3 
s3 = boto3.client('s3')

def list_bucket_contents(bucket_name):
   for object in s3.list_objects_v2(Bucket=bucket_name) :
      print(object.key)

list_bucket_contents('Mybucket') 

Jeśli jednak chcesz wyświetlić listę obiektów z segmentu w różnych regionach, musisz określić jawny parametr segmentu wymagany dla klienta.

import boto3 
backup_s3 = my_west_session.client('s3',region_name = 'us-west-2')
video_s3 = my_east_session.client('s3',region_name = 'us-east-1')

# you must pass boto3.Session.client and the bucket name 
def list_bucket_contents(s3session, bucket_name):
   response = s3session.list_objects_v2(Bucket=bucket_name)
   if 'Contents' in response:
     for obj in response['Contents']:
        print(obj['key'])

list_bucket_contents(backup_s3, 'backupbucket')
list_bucket_contents(video_s3 , 'videobucket') 
mootmoot
źródło
mniejszy. czy „obiekt” nie jest słowem kluczowym?
Swagatika,
Czy powinniśmy unikać używania zarówno „zasobu”, jak i „klienta” równolegle z jedną funkcją lub modułem?
John Overiron,
1
@JohnOveriron Nie wszystkie usługi AWS mają odpowiedniki „zasobów”, więc nadal potrzebujesz „klienta” niskiego poziomu. Jeśli zamierzasz używać do wdrożeń, zaleca się korzystanie z formowania w chmurze (trudno się go nauczyć, ale na dłuższą metę zaoszczędzi ci czasu) niż używanie API do automatyzacji wdrożeń.
mootmoot
@mootmoot Jednak kwerendy / manipulowanie usługami / zasobami aws można łatwo wykonać za pomocą tych interfejsów API zamiast pobierać dane wyjściowe lub aktualizować stos za pomocą formowania w chmurze. Mam rację?
SK Venkat,
@SKVenkat Jeśli zaczniesz budować wdrożenie na wielu serwerach, korzystając z ciągłej integracji itp., Formowanie chmury / terraform / heat jest znacznie łatwiejsze do utrzymania niż użycie kodu boto3.
mootmoot