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


当前回答

我会尽量简单地解释。因此,无法保证实际条款的准确性。

会话是启动到AWS服务的连接的地方。例如,下面是使用默认凭证配置文件的默认会话。~ /。aws/凭证,或假设您的EC2使用IAM实例配置文件)

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)

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

其他回答

客户端和资源是boto3 SDK中用于发出AWS服务请求的两个不同的抽象。如果您想使用boto3对AWS服务进行API调用,那么您可以通过客户端或资源进行调用。

您通常会选择使用客户端抽象或资源抽象,但您可以根据需要同时使用两者。我在下面列出了它们之间的区别,以帮助读者决定使用哪一种。

会话在很大程度上与客户端和资源的概念正交(但两者都使用)。

下面是关于客户端、资源和会话的详细信息。


客户:

this is the original boto3 API abstraction it provides low-level AWS service access all AWS service operations are supported by clients it exposes botocore client to the developer it typically maps 1:1 with the AWS service API it exposes snake-cased method names (e.g. ListBuckets API => list_buckets method) typically yields primitive, non-marshalled data (e.g. DynamoDB attributes are dicts representing primitive DynamoDB values) requires you to code result pagination it is generated from an AWS service description

下面是一个客户端级访问S3桶对象的例子:

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个对象。如果有超过1000个对象,则必须使用分页器或实现自己的循环,使用延续标记反复调用list_objects_v2()。

这就是底层客户端接口。现在进入更高级(更抽象)的Resource接口。


资源:

this is the newer boto3 API abstraction it provides a high-level, object-oriented API it does not provide 100% API coverage of AWS services it uses identifiers and attributes it has actions (operations on resources) it exposes sub-resources and collections of AWS resources typically yields marshalled data, not primitive AWS data (e.g. DynamoDB attributes are native Python values representing primitive DynamoDB values) does result pagination for you it is generated from an AWS resource description

下面是使用资源级访问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版本更简单、更紧凑,并且具有更多的功能(例如,它为您进行分页,并且它公开属性而不是原始字典)。如果您想要包含分页,代码的客户端版本实际上会比上面显示的更复杂。

最后,谈到会话,例如,会话是客户端和资源的基础,以及两者如何访问AWS凭证。


会话:

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

要了解更多关于这些boto3概念的信息,一个有用的资源是介绍性的“重新:发明”视频。


2023年1月更新:根据boto3文档中的资源页:

AWS Python SDK团队不打算在boto3的资源接口中添加新特性。现有的接口将在boto3的生命周期内继续运行。客户可以通过客户端接口访问更新的服务功能。

您可以在boto3/discussion /3563上阅读更多关于弃用资源的计划。

我会尽量简单地解释。因此,无法保证实际条款的准确性。

会话是启动到AWS服务的连接的地方。例如,下面是使用默认凭证配置文件的默认会话。~ /。aws/凭证,或假设您的EC2使用IAM实例配置文件)

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)

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