Разница в boto3 между ресурсом, клиентом и сессией?

Ответы:

249

Вот более подробная информация о клиенте , ресурсе и сеансе .

Клиент:

  • низкоуровневый доступ к сервису AWS
  • генерируется из описания сервиса AWS
  • выставляет клиента Botocore разработчику
  • обычно сопоставляет 1: 1 с сервисным API AWS
  • все операции сервиса AWS поддерживаются клиентами
  • имена методов в змеиной оболочке (например, API ListBuckets => метод 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'])

** вам придется использовать paginator или реализовать собственный цикл, повторно вызывая list_objects () с маркером продолжения, если их было больше 1000.

Ресурс:

  • высокоуровневый объектно-ориентированный API
  • генерируется из описания ресурса
  • использует идентификаторы и атрибуты
  • имеет действия (операции над ресурсами)
  • раскрывает субресурсы и коллекции ресурсов AWS
  • не обеспечивает 100% покрытие API сервисами AWS

Вот эквивалентный пример использования доступа на уровне ресурсов к объектам 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 создает сеанс по умолчанию для вас, когда это необходимо

Полезным ресурсом, чтобы узнать больше об этих концепциях boto3, является вступительное видео Re: Invent .

jarmod
источник
2
Есть ли разница в производительности между клиентом и ресурсом? У меня была эта проблема, когда удаление сообщений из очереди sqs было быстрее с помощью клиента и медленнее с использованием ресурса.
Vaulstein
3
@Vaulstein У меня нет каких-либо конкретных сравнений, но я бы, как правило, ожидал, что клиентские интерфейсы будут легче, чем ресурсы, и, следовательно, потенциально быстрее во время выполнения (хотя и медленнее для кодирования).
Джармод
@jarmod В рамках обучения я пытался создать корзину S3, используя оба метода. Я чувствую, что создание ресурса происходит быстрее при использовании «Клиента» по сравнению с «Ресурсом». Это правильно? Если так, то почему создание ресурса быстрее с Клиентом?
Сараванан Дж
1
@SaravananG Если вы s3.set_stream_logger('botocore'), вы можете увидеть логи метапрограммирования, которые boto3 (вызывает botocore) делает изнутри. Это работает, поэтому вам не нужно. Он имеет целую систему событий для настройки / подключения и глубокую таксономию событий 3 (+?) Для обработки запросов, анализа ответов и цепочки зависимых вызовов. Создание параметров, подписание запроса, определение региона заслуживают внимания. К вашему сведению, это волшебная боль, чтобы изменить. Вижу легкое изменение .
mcint
89

Я постараюсь объяснить это как можно проще. Таким образом, нет гарантии точности фактических сроков.

Сессия - это место, где можно инициировать подключение к сервисам 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)

Клиент - это объект класса низкого уровня. Для каждого вызова клиента необходимо явно указывать ресурсы таргетинга, назначенное имя цели службы должно быть длинным. Вы потеряете способность к абстракции.

Например, если вы имеете дело только с сеансом по умолчанию, это похоже на 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') 
mootmoot
источник
незначительный. не «объект» ключевое слово?
Свагатика
Должны ли мы избегать одновременного использования «ресурса» и «клиента» в одной функции или модуле?
Джон Оверирон
1
@JohnOveriron Не у всех сервисов AWS есть «ресурсный» аналог, поэтому вам все еще нужен «клиент» низкого уровня. Если вы намереваетесь использовать для развертываний, рекомендуется использовать облачную информацию (это сложно изучить, но сэкономит ваше время в долгосрочной перспективе), чем использовать API для автоматизации развертываний.
mootmoot
@mootmoot Но эти API-интерфейсы могут легко выполнять запрос / управление службами / ресурсами aws, а не извлекать выходные данные или обновлять стек посредством облачной информации. Я прав?
СК Венкат
@SKVenkat Если вы начнете создавать многосерверное развертывание, используя непрерывную интеграцию и т. Д., Облачность / terraform / heat гораздо проще поддерживать, чем при использовании кода boto3.
mootmoot