Différence de boto3 entre la ressource, le client et la session?

Réponses:

249

Voici quelques informations plus détaillées sur le client , la ressource et la session .

Client:

  • accès au service AWS de bas niveau
  • généré à partir de la description du service AWS
  • expose le client botocore au développeur
  • mappe généralement 1: 1 avec l'API de service AWS
  • toutes les opérations de service AWS sont prises en charge par les clients
  • noms de méthodes en serpent (par exemple API ListBuckets => méthode list_buckets)

Voici un exemple d'accès au niveau client aux objets d'un compartiment S3 (au plus 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'])

** vous devrez utiliser un paginateur , ou implémenter votre propre boucle, en appelant list_objects () à plusieurs reprises avec un marqueur de continuation s'il y en avait plus de 1000.

Ressource:

  • API orientée objet de niveau supérieur
  • générée à partir de la description de la ressource
  • utilise des identifiants et des attributs
  • a des actions (opérations sur les ressources)
  • expose les sous-ressources et les collections de ressources AWS
  • ne fournit pas une couverture API à 100% des services AWS

Voici l'exemple équivalent utilisant l'accès au niveau des ressources aux objets d'un compartiment S3 (tous):

import boto3

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

Notez que dans ce cas, vous n'avez pas à effectuer un deuxième appel d'API pour obtenir les objets; ils sont à votre disposition en tant que collection sur le seau. Ces collections de sous-ressources sont chargées paresseusement.

Vous pouvez voir que la Resourceversion du code est beaucoup plus simple, plus compacte et a plus de capacités (elle fait la pagination pour vous). leClient version du code serait en fait plus compliquée que celle illustrée ci-dessus si vous vouliez inclure la pagination.

Session:

  • stocke les informations de configuration (principalement les informations d'identification et la région sélectionnée)
  • vous permet de créer des clients et des ressources de service
  • boto3 crée une session par défaut pour vous en cas de besoin

Une vidéo utile pour en savoir plus sur ces concepts boto3 est la vidéo d'introduction re: Invent .

jarmod
la source
2
Y a-t-il une différence de performances entre le client et la ressource? J'ai eu ce problème où la suppression de messages de la file d'attente sqs était plus rapide à l'aide du client et plus lente à l'aide des ressources.
Vaulstein
3
@Vaulstein Je n'ai pas de comparaisons spécifiques à partager, mais je m'attendrais généralement à ce que les interfaces client soient plus légères que les ressources et donc potentiellement plus rapides à l'exécution (bien que plus lentes à coder).
jarmod
@jarmod Dans le cadre de l'apprentissage, j'ai essayé de créer le compartiment S3 en utilisant les deux méthodes. Je pense que la création de ressources se produit plus rapidement lors de l'utilisation de "Client" par rapport à "Resource". Est ce juste? Si oui, pourquoi la création de ressources est plus rapide avec Client?
Saravanan G
1
@SaravananG Si vous s3.set_stream_logger('botocore'), vous pouvez voir les journaux de la méta-programmation que boto3 (appelant à botocore) fait sous le capot. Cela fonctionne, vous n'avez donc pas à le faire. Il dispose d'un système d'événement complet pour la personnalisation / connectabilité et d'une taxonomie profonde des événements 3 (+?), Pour gérer la préparation des demandes, l'analyse des réponses et le chaînage des appels dépendants. La construction de paramètres, la signature de demande, la détection de région sont à noter. Pour info c'est une douleur magique à modifier. Voir changement facile .
mcint
89

Je vais essayer de l'expliquer le plus simplement possible. Il n'y a donc aucune garantie de l'exactitude des termes réels.

La session est l'endroit où initier la connectivité aux services AWS. Par exemple, la session par défaut suivante utilise le profil d'informations d'identification par défaut (par exemple, ~ / .aws / credentials, ou suppose que votre EC2 utilise le profil d'instance IAM)

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

Étant donné que la session par défaut est limitée au profil ou au profil d'instance utilisé, vous devez parfois utiliser la session personnalisée pour remplacer la configuration de session par défaut (par exemple, region_name, endpoint_url, etc.), par exemple

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

Ressource : il s'agit de la classe de service de haut niveau recommandée à utiliser. Cela vous permet de lier des ressources AWS particulières et de les transmettre, de sorte que vous n'utilisez cette abstraction que pour vous soucier des services cibles vers lesquels vous pointez. Comme vous le constatez dans la partie session, si vous avez une session personnalisée, vous passez simplement cet objet abstrait plutôt que de vous soucier de toutes les régions personnalisées, etc. à transmettre. Voici un exemple compliqué Par exemple

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)

Le client est un objet de classe de bas niveau. Pour chaque appel client, vous devez spécifier explicitement les ressources de ciblage, le nom cible du service désigné doit être long. Vous perdrez la capacité d'abstraction.

Par exemple, si vous ne traitez qu'avec la session par défaut, cela ressemble à 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') 

Toutefois, si vous souhaitez répertorier les objets d'un compartiment dans différentes régions, vous devez spécifier le paramètre de compartiment explicite requis pour le client.

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') 
sans objet
la source
mineur. 'objet' n'est-il pas un mot-clé?
Swagatika
Faut-il éviter d'utiliser à la fois «ressource» et «client» en parallèle une fonction ou un module?
John Overiron
1
@JohnOveriron Tous les services AWS n'ont pas d'équivalent "ressource", vous avez donc toujours besoin du "client" de bas niveau. Si vous avez l'intention d'utiliser pour les déploiements, il est recommandé d'utiliser cloudformation (il est difficile à apprendre mais vous fera gagner du temps à long terme) que d'utiliser l'API pour automatiser les déploiements.
mootmoot
@mootmoot Mais interroger / manipuler des services / ressources aws peut être fait facilement par ces API plutôt que d'aller chercher des sorties ou de mettre à jour la pile via cloudformation. Ai-je raison?
SK Venkat
@SKVenkat Si vous commencez à construire un déploiement multi-serveur, en utilisant une intégration continue, etc., cloudformation / terraform / heat est beaucoup plus facile à maintenir qu'en utilisant le code boto3.
mootmoot