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


215

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

回答:


247

ここに、ClientResource、およびSessionのすべてに関する詳細情報があります。

クライアント:

  • 低レベルのAWSサービスアクセス
  • AWS サービスの説明から生成
  • botocoreクライアントを開発者に公開します
  • 通常、AWSサービスAPIと1:1でマッピングします
  • すべてのAWSサービス操作はクライアントによってサポートされています
  • ヘビの場合のメソッド名(例:ListBuckets API => list_bucketsメソッド)

S3バケットのオブジェクトへのクライアントレベルのアクセスの例を以下に示します(最大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'])

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

資源:

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

S3バケットのオブジェクト(すべて)にリソースレベルのアクセスを使用する同等の例を次に示します。

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ビデオの紹介です。


2
クライアントとリソースの間にパフォーマンスの違いはありますか?sqsキューからのメッセージの削除がクライアントを使用すると速くなり、リソースを使用すると遅くなるという問題がありました。
Vaulstein、2013

3
@Vaulstein共有する特定の比較はありませんが、通常、クライアントインターフェイスはリソースよりも軽量であり、実行時に高速になる可能性があります(ただし、コード化は遅くなります)。
jarmod 2018

@jarmod学習の一環として、両方の方法を使用してS3バケットを作成しようとしました。「リソース」よりも「クライアント」を使用した方がリソースの作成が早くなると思います。正しいですか?もしそうなら、なぜリソース作成はクライアントでより速いのですか?
サラバナンG

1
@SaravananG場合はs3.set_stream_logger('botocore')、boto3(botocoreを呼び出す)が内部で行うメタプログラミングのログを確認できます。動作するので、必要はありません。カスタマイズ/プラガビリティのためのイベントシステム全体と、イベントの3(+?)深い分類法があり、要求の準備、応答の解析、依存する呼び出しのチェーンを処理します。パラメータの構築、リクエストの署名、リージョンの検出は注目に値します。ちなみに、修正するのは魔法のような痛みです。簡単な変更を参照してください
mcint

89

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

セッションは、AW​​Sサービスへの接続を開始する場所です。たとえば、以下は、デフォルトの認証情報プロファイルを使用するデフォルトのセッションです(例:〜/ .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_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')

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

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)

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

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

マイナー。「オブジェクト」はキーワードではありませんか?
スワガティカ

「リソース」と「クライアント」の両方を1つの関数またはモジュールで同時に使用することを避けるべきですか?
John Overiron

1
@JohnOverironすべてのAWSサービスに対応する「リソース」があるわけではないため、低レベルの「クライアント」が必要です。デプロイメントに使用する場合は、APIを使用してデプロイメントを自動化するよりも、cloudformationを使用することをお勧めします(学ぶのは難しいですが、長期的には時間を節約できます)。
mootmoot 2018

@mootmootしかし、awsサービス/リソースのクエリ/操作は、cloudformationを通じて出力を取得したりスタックを更新したりするのではなく、これらのAPIによって簡単に実行できます。私は正しいですか?
SK Venkat 2018

@SKVenkat yuuが継続的な統合などを使用してマルチサーバーデプロイメントの構築を開始する場合、boto3コードを使用するよりもcloudformation / terraform / heatを維持する方がはるかに簡単です。
mootmoot
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.