Этот пост изначально появился на внутреннем блоге компании, а также адаптирован здесь с разрешения.
BOTO3 Является ли Python SDK для AWS. Это делает отличную работу, делая AWS APIS, чувствующ ротон Python. Этот пост – любовное письмо к одной конкретной функции – Paginators Отказ
Ну, это то, что или оправдание, чтобы повеселиться с сообщением об ошибке «Объект страницы не является итератор»
API и пагинация в двух словах
Когда вам нужно получить список объектов из сервиса, большинство API будут вернуть этот список в кусках, если существует большое количество результатов. Это обычно хорошая вещь для всех:
- API может получить вам одну страницу результатов быстрее, чем может отправить все
- Вы можете начать работать рано
- Если вы бросаетесь в середине обработки, есть менее потраченные усилия
Все выигрывают!
BOTO3 и Pagination – DIY Mode
Когда AWS API вернет усеченный ответ, они включают в себя токен, который вы можете использовать для получения следующей страницы результатов.
Если вам нужно создать полный результат, установленный из страничных ответов, один вариант – обрабатывать все самостоятельно. Например, вот один из способов вы можете получить История ценообразования на месте В первый день октября 2019 года:
import boto3 from datetime import datetime ec2 = boto3.client('ec2') params = { 'StartTime': datetime(2019,10,1), 'EndTime': datetime(2019,10,1) } results = [] while params.get('NextToken') != '': response = ec2.describe_spot_price_history(**params) results.extend(response['SpotPriceHistory']) params['NextToken'] = response['NextToken']
Это не самый чистый код, но нести меня на мгновение. Обратите внимание на словарные ключевые ключи, которые вам нужно возиться вручную:
NextToken
Возвращается в пагированное отклика, и вы кормите его в последующий запрос, чтобы получить другую страницу результатовSpotPriceSistory
где вы смотрите в каждый ответ на данные результата, которые вы заботитесь о
Может быть легко смешать вещи при обращении этих токенов, и сделать вещи более интересными, точные правила Paginator варьируются по службе. См. Отличное резюме IAN MCKAY в IANN0036/AWS-Pagination – правила Чтобы увидеть, насколько разнообразны эти правила.
BOTO3 включает в себя полезные Paginator Абстракция, которая делает весь этот процесс намного более гладкой. Чтобы получить коллекцию объемов EBS, например, вы можете сделать что-то подобное:
client = boto3.client('ec2') paginator = client.get_paginator('describe_volumes') vols = (vol for page in paginator.paginate() for vol in page['Volumes'])
Абстракция Paginator помогает бумаги над различиями между услугами и скрывает кучу деталей под ковриком Так что вам не нужно заботиться о них.
Мое растерянность
На какой-то момент вскоре после изучения пагинаторов Boto3 я экспериментировал с некоторым кодом и хотел посмотреть только на первую страницу результатов. Видеть это Paginate ()
Возвращает Pagterterator
Я подумал, что смогу сделать что-то вроде этого:
page_iter = paginator.paginate() first_page = next(page_iter)
Но нет! Я вернул это сообщение об ошибке:
TypeError: PageIterator object is not an iterator
Чего ждать?
Поэтому у меня был объект, который называл себе итератором и отлично работал в цикле. Но это не будет работать с Далее ()
или индекс (например, Page_iter [0]
). Как обходной путь, я попробовал это:
page_iter = iter(paginator.paginate()) first_page = next(page_iter)
И … это сработало. Я не совсем понял Почему Это сработало или было необходимо в первую очередь. Я только что решил по какой-то странной причине, которую я должен был сделать Явно Что за цикл делал неявно . Это было не то, что мне нужно было сделать все это часто, поэтому я не давал ему слишком много мысли.
Поваренная книга разъясняет
Быстро пересылая немного, я прочитал отличный | Дэвид Безли Python Cookbook Отказ Рецепт 4.6 в 3-м издании называется «Определение генераторных функций с дополнительным состоянием». Кратко описывает, что Boto3’s Pagterterator
делает и почему. Рецепт открывается с этим:
Проблема: Вы хотели бы определить функцию генератора, но она включает в себя дополнительное состояние, которое вы хотели бы как-то разоблачить пользователю. (Beazley, Дэвид; Джонс, Брайан К .. Python Cookbook: рецепты для освоения Python 3 (стр. 120). О’Рейли СМИ.)
Как оказывается, это именно проблема Pagterterator
решает. Это должно:
- Итайте через некоторые данные. В этом случае страницы от ответа API.
- Выдержать дополнительное состояние и функциональность пользователю. Например, отслеживать резюме токен что вызывающий абонент может использовать для возобновления прерванной пагинации. Или предложить Поиск Метод, который может найти записи, соответствующие A Jmespath выражение по страницам ответа.
Есть несколько удобных вещей под крышками Pagterterator
сорт! Но в обычном случае, когда вы попадаете в петлю для цикла (или вызовите iTer ()
явно), он вызывает класс __iter __ ()
«Магический» метод за кулисами.
Итак, наверно, добыча, Pagterterator
Является ли точное имя (позволяет вам повторять страницы) и вводящего в заблуждение один (он не поддерживает непосредственно протокол iTerator Python). Это больше ведет себя как потенциал :
Iterables можно использовать в цикле и во многих других местах, где требуется последовательность ( ZIP ()
, Карта ()
, …). Когда объект ITERABLE пропускается как аргумент в встроенной функции ИТЭР ()
он возвращает итератор для объекта. Этот итератор хороший для одного прохода над набором значений. При использовании iTerables обычно не нужно звонить ИТЭР ()
Или разобраться с объектами итератора. Заявление о том, что это автоматически для вас, создавая временную неназванную переменную для удержания итератора в течение длительности цикла. Смотрите также итератор, последовательность и генератор.
Trey Hunner делает отличную работу по поводу обсуждения этих концепций четко. Есть полезные разделы в обоих Протокол итератора: Как «за петли» работают в Python а также Как сделать итератор в Python которые имеют отношение к пониманию Pagterterator. ‘s поведение.
Для тех, кто сделал это так далеко и заинтересован в реальном коде, Pagterterator
определяется здесь Отказ
Заворачивать
Я изначально написал этот пост на блоге внутренней компании пару лет назад. Я сделал несколько незначительных обновлений, но содержание в основном то же самое. Как я писал в то время, возможно, что я только думаю Я понимаю этот материал! Вопросы, комментарии и критика приветствуются в комментариях. Спасибо за прочтение!
Самое главное, если вы заметите любую откровенную ерунду здесь, пожалуйста, позвоните мне (публично или в частном порядке), чтобы я мог получить его, прежде чем ведать какие-либо невинные сбивцы с пути. Спасибо.
Оригинал: “https://dev.to/ajkerrigan/the-iterator-that-wasn-t-a-love-letter-to-boto3-paginators-1nc3”