资源,客户端和会话之间的boto3差异?

shi*_*iva 173 python boto3

我在Ubuntu 16.04 LTS中使用Python 2.7.12.我正在学习如何使用以下链接中的boto3:https://boto3.readthedocs.io/en/latest/guide/quickstart.html#using-boto-3 .我怀疑的是何时使用资源,客户端或会话以及它们各自的功能.

jar*_*mod 171

添加到其他答案,特别是在比较客户端与资源时.

客户:

  • 低级服务访问
  • 服务描述生成
  • 将botocore客户端暴露给开发人员
  • 通常使用服务API以1:1映射
  • 蛇形方法名称(例如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'])
Run Code Online (Sandbox Code Playgroud)

**你必须使用一个paginator,或者实现你自己的循环,如果超过1000,用一个continuation标记重复调用list_objects().

资源:

  • 更高级的,面向对象的API
  • 资源描述生成
  • 使用标识符和属性
  • 有行动(对资源的操作)
  • 公开子资源和集合

以下是使用对S3存储桶对象(全部)的资源级访问的等效示例:

import boto3

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

请注意,在这种情况下,您不必进行第二次API调用来获取对象; 它们可以作为桶上的集合使用.这些子资源集合是延迟加载的.

会议:

  • 存储配置信息(主要是凭据和选定区域)
  • 允许您创建服务客户端和资源

有关这些boto3概念的更多信息的有用资源是介绍性的re:Invent视频.

  • 令人遗憾的是官方文档混淆了“客户端”和“资源”而没有任何进一步的解释。 (5认同)
  • @Vaulstein我没有任何特定的比较分享,但我通常希望客户端接口比资源更轻,因此在运行时可能更快(尽管编码速度较慢). (3认同)
  • 客户端和资源之间是否存在性能差异?我遇到了这个问题,使用客户端从 sqs 队列中删除消息速度更快,而使用资源速度更慢。 (2认同)
  • @SaravananG 如果您使用 `s3.set_stream_logger('botocore')`,您可以看到 boto3(调用 botocore)在后台执行的元编程日志。它确实有效,因此您不必这样做。它有一个用于定制/可插入性的完整事件系统和一个 3(+?) 深度事件分类法,用于处理请求准备、响应解析和链接依赖调用。参数构建、请求签名、区域检测是值得注意的。仅供参考,修改是一种神奇的痛苦。[查看简单更改](https://gist.github.com/gleicon/2b8acb9f9c0f22753eaac227ff997b34)。 (2认同)

moo*_*oot 79

我会尝试解释它尽可能简单.因此无法保证实际条款的准确性.

会话是启动与AWS服务的连接的地方.例如,以下是使用默认凭证配置文件的默认会话(例如〜/ .aws/credentials,或假设您的EC2使用IAM实例配置文件)

sqs = boto3.client('sqs')
s3 = boto3.resource('s3')
Run Code Online (Sandbox Code Playgroud)

由于默认会话是对使用的配置文件或实例配置文件的限制,因此有时您需要使用自定义会话来覆盖默认会话配置(例如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')
Run Code Online (Sandbox Code Playgroud)

资源:这是建议使用的高级服务类.这允许您绑定特定AWS资源并将其传递,因此您只需使用此抽象而不是担心指向哪个目标服务.正如您从会话部分注意到的那样,如果您有自定义会话,则只需传递此抽象对象,而不是担心所有自定义区域等都要传递.以下是一个复杂的例子Eg

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)
Run Code Online (Sandbox Code Playgroud)

客户端是一个低级别的对象.对于每个客户端调用,您需要明确指定目标资源,指定的服务目标名称必须传递长.你将失去抽象能力.

例如,如果您只处理默认会话,则看起来类似于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') 
Run Code Online (Sandbox Code Playgroud)

但是,如果要在不同区域中列出来自存储桶的对象,则需要指定客户端所需的显式存储桶参数.

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') 
Run Code Online (Sandbox Code Playgroud)