Diferença no boto3 entre recurso, cliente e sessão?

Respostas:

248

Aqui estão algumas informações mais detalhadas sobre o que é Cliente , Recurso e Sessão .

Cliente:

  • acesso de serviço da AWS de baixo nível
  • gerado a partir da descrição do serviço da AWS
  • expõe o cliente botocore ao desenvolvedor
  • normalmente mapeia 1: 1 com a API de serviço da AWS
  • todas as operações de serviço da AWS são suportadas pelos clientes
  • nomes de métodos em forma de cobra (por exemplo, API ListBuckets => método list_buckets)

Aqui está um exemplo de acesso no nível do cliente aos objetos de um bucket do S3 (no máximo 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'])

** você precisaria usar um paginador ou implementar seu próprio loop, chamando list_objects () repetidamente com um marcador de continuação se houvesse mais de 1000.

Recurso:

  • API orientada a objetos de nível superior
  • gerado a partir da descrição do recurso
  • usa identificadores e atributos
  • possui ações (operações sobre recursos)
  • expõe sub-recursos e coleções de recursos da AWS
  • não fornece 100% de cobertura da API dos serviços da AWS

Aqui está o exemplo equivalente usando acesso em nível de recurso aos objetos de um bucket do S3 (todos):

import boto3

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

Observe que, nesse caso, você não precisa fazer uma segunda chamada de API para obter os objetos; eles estão disponíveis para você como uma coleção no balde. Essas coleções de sub-recursos são carregadas lentamente.

Você pode ver que a Resourceversão do código é muito mais simples, mais compacta e tem mais capacidade (faz paginação para você). A Clientversão do código seria realmente mais complicada do que a mostrada acima, se você quisesse incluir paginação.

Sessão:

  • armazena informações de configuração (principalmente credenciais e região selecionada)
  • permite criar clientes e recursos de serviço
  • O boto3 cria uma sessão padrão para você quando necessário

Um recurso útil para aprender mais sobre esses conceitos do boto3 é o re: Invent video .

jarmod
fonte
2
Existe alguma diferença de desempenho entre cliente e recurso? Eu tive esse problema em que a exclusão de mensagens da fila sqs era mais rápida usando o cliente e mais lenta usando o recurso.
Vaulstein
3
@ Vaulstein Não tenho comparações específicas para compartilhar, mas geralmente espero que as interfaces do cliente sejam mais leves que os recursos e, portanto, potencialmente mais rápidas em tempo de execução (embora sejam mais lentas para codificar).
jarmod
@jarmod Como parte do aprendizado, tentei criar um bucket S3 usando os dois métodos. Eu sinto que, a criação de recursos está acontecendo mais rapidamente ao usar o "Cliente" em comparação com o "Recurso". Está certo? Se sim, por que a criação de recursos é mais rápida com o Client?
Saravanan G
1
@SaravananG Se você s3.set_stream_logger('botocore'), você pode ver os logs da metaprogramação que o boto3 (chamando ao botocore) faz por baixo. Funciona para que você não precise. Possui um sistema de eventos completo para customização / plugabilidade e uma taxonomia profunda de 3 (+?) Eventos, para lidar com a preparação de solicitações, análise de respostas e encadeamento de chamadas dependentes. A construção de parâmetros, a solicitação de assinatura e a detecção de região são dignas de nota. Para sua informação, é uma dor mágica modificar. Veja mudanças fáceis .
mcint 6/02/19
89

Vou tentar explicar o mais simples possível. Portanto, não há garantia da precisão dos termos reais.

Sessão é onde iniciar a conectividade com os serviços da AWS. Por exemplo, a seguir é a sessão padrão que usa o perfil de credencial padrão (por exemplo, ~ / .aws / credentials ou assume seu EC2 usando o perfil de instância do IAM)

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

Como a sessão padrão é o limite para o perfil ou perfil de instância usado, às vezes você precisa usar a sessão personalizada para substituir a configuração da sessão padrão (por exemplo, region_name, endpoint_url, etc.)

# 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')

Recurso : esta é a classe de serviço de alto nível recomendada para ser usada. Isso permite que você vincule determinados recursos da AWS e os repasse, para que você use essa abstração apenas para se preocupar com os serviços de destino. Como você notou na parte da sessão, se você tiver uma sessão personalizada, basta passar este objeto abstrato do que se preocupar com todas as regiões personalizadas, etc. A seguir, é apresentado um exemplo complicado

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)

Cliente é um objeto de classe de baixo nível. Para cada chamada de cliente, você precisa especificar explicitamente os recursos de segmentação, o nome da meta de serviço designada deve ser longo. Você perderá a capacidade de abstração.

Por exemplo, se você lida apenas com a sessão padrão, isso é semelhante ao 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') 

No entanto, se você quiser listar objetos de um bucket em diferentes regiões, precisará especificar o parâmetro explícito do bucket necessário para o cliente.

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
fonte
menor. 'objeto' não é uma palavra-chave?
Swagatika
Devemos evitar o uso de 'recurso' e 'cliente' em paralelo com uma função ou módulo?
John Overiron
1
@JohnOveriron Nem todos os serviços da AWS têm uma contrapartida de "recursos", portanto você ainda precisa do "cliente" de baixo nível. Se você pretende usar para implantações, é recomendável usar a formação em nuvem (é difícil aprender, mas economizará tempo a longo prazo) do que usar a API para automatizar implantações.
mootmoot
@mootmoot Mas a consulta / manipulação de serviços / recursos do aws pode ser feita facilmente por essas APIs, em vez de buscar saídas ou atualizar a pilha através da formação da nuvem. Estou correcto?
SK Venkat
@SKVenkat Se você começar a criar a implantação de vários servidores, usando a integração contínua etc., a formação de nuvens / terraform / heat é muito mais fácil de manter do que usar o código boto3.
mootmoot