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


215

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

Answers:


246

这里是有关ClientResourceSession的所有更详细的信息。

客户:

  • 低级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)

请注意,在这种情况下,您无需进行第二次API调用即可获取对象。您可以将其作为存储桶中的集合使用。这些子资源集合是延迟加载的。

您可以看到Resource该代码的版本更简单,更紧凑并且具有更多功能(它可以为您分页)。Client如果要包括分页,代码的版本实际上比上面显示的要复杂。

会议:

  • 存储配置信息(主要是凭据和所选区域)
  • 允许您创建服务客户端和资源
  • boto3在需要时为您创建一个默认会话

re:Invent video入门视频是了解这些boto3概念的有用资源。


2
客户端和资源之间是否存在性能差异?我有这样的问题,即使用客户端从sqs队列删除消息的速度更快,而使用资源的速度较慢。
Vaulstein '18年

3
@Vaulstein我没有任何特定的比较可共享,但是我通常希望客户端接口比资源更轻量,因此在运行时可能更快(尽管针对代码的速度较慢)。
jarmod

@jarmod作为学习的一部分,我尝试使用两种方法创建S3存储桶。我认为,与“资源”相比,使用“客户端”进行资源创建的速度更快。这样对吗?如果是这样,为什么使用Client可以更快地创建资源?
Saravanan G

1
@SaravananG如果您愿意s3.set_stream_logger('botocore'),可以查看boto3(调用botocore)在后台进行的元编程日志。它确实起作用,所以您不必这样做。它具有用于自定义/可插入性的整个事件系统以及3(+?)个深度的事件分类法,可处理请求准备,响应解析和链接依赖的调用。参数构建,请求签名,区域检测值得注意。仅供参考,修改是一个神奇的痛苦。看到容易改变
mcint

89

我将尽力解释它。因此,不能保证实际条款的准确性。

会话是启动与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_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') 

次要。“对象”不是关键字吗?
Swagatika

我们是否应该避免同时使用一个功能或模块的“资源”和“客户端”?
约翰·奥弗隆

1
@JohnOveriron并非所有的AWS服务都具有“资源”对应项,因此您仍然需要低级的“客户端”。如果打算用于部署,建议使用cloudformation(这很难学习,但从长远来看会节省您的时间),而不是使用API​​来自动化部署。
mootmoot18年

@mootmoot但是,通过这些API可以轻松查询/操纵AWS服务/资源,而不是通过cloudformation获取输出或更新堆栈。我对么?
SK Venkat

@SKVenkat如果您开始使用连续集成等方法开始构建多服务器部署,那么使用boto3代码可以更轻松地维护cloudformation / terraform / heat。
mootmoot18年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.