web-dev-qa-db-ja.com

リソース、クライアント、およびセッション間のboto3の違いは?

Ubuntu 16.04 LTSでPython 2.7.12を使用しています。私は次のリンクからboto3の使い方を学んでいます: https://boto3.readthedocs.io/en/latest/guide/quickstart.html#using-boto-3 。私の疑問は、リソース、クライアント、またはセッション、そしてそれぞれの機能をいつ使用するかです。

125
shiva

これは ClientResource 、および Session についての詳細な情報です。

クライアント:

  • 低レベルのサービスアクセス
  • service descriptionから生成されます
  • ボトコアクライアントを開発者に公開する
  • 通常、サービスAPIと1:1で対応します。
  • すべてのサービス操作はクライアントによってサポートされています
  • スネークケースのメソッド名(例:ListBuckets API => list_bucketsメソッド)

これは、S3バケットのオブジェクトへのクライアントレベルのアクセスの例です(最大1000 **)。

import boto3

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

** 1000以上の場合は、 paginator を使用するか、独自のループを実装し、継続マーカーを使用してlist_objects()を繰り返し呼び出す必要があります。

リソース:

  • 高レベルのオブジェクト指向API
  • resource descriptionから生成された
  • 識別子と属性を使う
  • アクションを持つ(リソースに対する操作)
  • サブリソースとコレクションを公開します
  • 100%のAPIカバレッジを提供していません

これは、S3バケットのオブジェクト(all)へのリソースレベルのアクセスを使用した同等の例です。

import boto3

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

この場合、オブジェクトを取得するために2回目のAPI呼び出しを行う必要はありません。それらはバケツのコレクションとしてあなたに利用可能です。これらのサブリソースのコレクションは遅延ロードされます。

Resourceバージョンのコードは、はるかに単純でコンパクトで、機能も豊富です(ページ付けが行われます)。 Clientバージョンのコードは、実際にページ区切りを含めたい場合には、上に示したものよりも複雑になります。

セッション:

  • 構成情報(主に資格情報と選択された地域)を保管します。
  • サービスのクライアントとリソースを作成できます
  • boto3は必要に応じてあなたのためにデフォルトセッションを作成します

これらのboto3の概念についてもっと学ぶのに役立つリソースは 紹介re:Invent video です。

108
jarmod

できるだけ簡単に説明します。そのため、実際の用語の正確性は保証されていません。

Sessionは、AWSサービスへの接続を開始する場所です。例えば。以下は、デフォルトの認証情報プロファイルを使用するデフォルトセッションです(例:〜/ .aws/credentials、またはIAMインスタンスプロファイルを使用しているEC2を想定)。

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

デフォルトセッションは使用されるプロファイルまたはインスタンスプロファイルに制限されているため、場合によってはカスタムセッションを使用してデフォルトセッション設定(たとえば、region_name、endpoint_urlなど)を上書きする必要があります。

# custom resource session must use boto3.Session to do the override
my_west_session = boto3.Session(region_name = 'us-west-2')
my_east_sesison = boto3.Session(region_name = 'us-east-1')
backup_s3 = my_west_session.resource('s3')
video_s3 = my_east_sesison.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')

リソース:これは、使用が推奨される高レベルのサービスクラスです。これにより、特定のAWSリソースを結び付けて渡すことができるため、どのターゲットサービスが指定されているかを心配するよりも、この抽象概念を使用するだけです。セッション部分からわかるように、カスタムセッションがある場合は、すべてのカスタム領域などを心配するよりも、この抽象オブジェクトを渡すだけです。以下は複雑な例です。

import boto3 
my_west_session = boto3.Session(region_name = 'us-west-2')
my_east_sesison = boto3.Session(region_name = 'us-east-1')
backup_s3 = my_west_session.resource("s3")
video_s3 = my_east_sesison.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)

Clientは低レベルのクラスオブジェクトです。クライアント呼び出しごとに、ターゲティングリソースを明示的に指定する必要があります。指定されたサービスターゲット名は、長く渡す必要があります。あなたは抽象化能力を失うでしょう。

たとえば、デフォルトセッションのみを扱う場合、これは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') 

ただし、異なる地域のバケットからオブジェクトを一覧表示する場合は、クライアントに必要な明示的なバケットパラメータを指定する必要があります。

import boto3 
backup_s3 = my_west_session.client('s3',region_name = 'us-west-2')
video_s3 = my_east_sesison.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') 
67
mootmoot