Ускоренный курс по использованию Python и API Google для автоматизации всего, что вы делаете с Gmail, Google Диском, Календарем или любым другим API Google.

У Google буквально сотни API, в том числе для Gmail, Диска, Карт, перевода, аналитики и многого другого. Все они имеют одни и те же концепции, такие как авторизация, нумерация страниц или загрузка/выгрузка мультимедиа. В этой статье мы рассмотрим все эти концепции, а также запачкаем руки некоторыми из вышеупомянутых API, чтобы узнать обо всех интересных вещах, которые вы можете делать с любыми API Google.

Настройка

Чтобы получить доступ к API, нам нужно сначала создать проект в Google Cloud. Для этого перейдите в Cloud Resource Manager и нажмите Создать проект. Кроме того, вы можете сделать это также через CLI, используя gcloud projects create $PROJECT_ID. Через несколько секунд вы увидите новый проект в списке.

Далее нам нужно включить API для этого проекта. Вы можете найти все доступные API в Библиотеке API. Те, с которыми мы будем играть в следующих разделах, включают Gmail, Диск и Формы, но вы выбираете, что вы хотите включить.

Теперь API готов к использованию, но нам нужны учетные данные для доступа к нему. Существует несколько различных типов учетных данных в зависимости от типа приложения. Большинство из них подходят для приложений, которые требуют/запрашивают согласие пользователя, таких как клиентские (настольные) приложения или приложения для Android/iOS. Предпочтительным типом учетных данных для нас будет служебная учетная запись, поскольку она подходит для автоматизации, то есть для доступа без взаимодействия с пользователем. Однако учетные данные служебной учетной записи не работают со многими API — например, Photos API не поддерживает его, а все API Google Workspace (GSuite) (например, Gmail, Sheets, Docs…) разрешают его, только если у вас есть свой Workspace с делегированием общедоменного доступа. Поэтому единственным вариантом для нас является использование учетных данных OAuth.

Чтобы создать учетные данные OAuth, перейдите на страницу учетных данных, нажмите Создать учетные данные и выберите Идентификатор клиента OAuth. Вам будет предложено настроить экран согласия OAuth, продолжайте и создайте его — на первом экране вам будет предложено выбрать тип пользователя, мы выберем Внешний.

На следующем экране вы укажете название приложения, электронный адрес службы поддержки пользователей и адрес электронной почты в разделе контактная информация разработчика. После этого вы можете нажать Сохранить и продолжить, пропустив раздел Области действия. В разделе Тестовые пользователи нажмите Добавить пользователей и добавьте адреса электронной почты учетных записей Google, которые вы будете использовать для тестирования (возможно, вам потребуется создать дополнительные учетные записи Google). учитывайте это), снова нажмите Сохранить и продолжить. В общем, конфигурация должна выглядеть примерно так:

Теперь нам нужно вернуться на страницу учетных данных, нажать Создать учетные данные и выбрать Идентификатор клиента OAuth. Затем мы выберем Тип приложения как Настольное приложение и дадим ему какое-то имя:

Вам будет представлен идентификатор клиента и секрет клиента — нажмите кнопку Загрузить JSON, чтобы сохранить их под именем credentials.json — мы воспользуемся ими через мгновение.

После этого у нас теперь есть проект с включенным API и экраном приложения/согласия OAuth, который позволит нам авторизовать доступ к выбранным нами API и областям.

Наконец, нам нужно установить клиентские библиотеки Python, чтобы использовать API. Нам нужно 2 из них, один для аутентификации и один для реальных API Google:

Доступ к API

Теперь мы готовы начать писать код на Python. Первое, что нам нужно сделать, это аутентифицироваться и получить согласие пользователя:

Начнем с определения областей доступа для доступа к API. Чтобы узнать, какие из них вам нужны, выполните поиск по запросу "scope" на конкретной странице документации API. Первый результат должен вести на страницу, например, такую. этот для Gmail или Фото. Выберите все нужные вам прицелы и добавьте их в список SCOPES. Здесь мы выбираем gmail.readonly для целей тестирования.

Затем мы проверяем наличие файла token.json, в котором хранятся токены доступа и обновления пользователя. Этот файл создается автоматически, когда поток авторизации завершается в первый раз. Если файл существует, но хранящиеся в нем учетные данные недействительны, мы пытаемся их обновить. Если файл отсутствует, мы позволяем пользователю войти в систему через поток OAuth. Откроется вкладка браузера с запросом на вход. Здесь вы должны использовать тестового пользователя, указанного вами во время настройки экрана OAuth.

После принятия областей, запрашиваемых приложением, будет создан файл token.json. Когда вы снова запустите этот код аутентификации, токен будет использоваться (при условии, что срок его действия не истек), поэтому вам не нужно будет снова подтверждать его в браузере.

Если вы решите изменить области в какой-то момент, обязательно удалите token.json, потому что приложение нужно будет повторно авторизовать.

Основы

Тот факт, что клиентская библиотека Google API Python включает функции для всех API Google, делает ее очень сложной и трудной для навигации. Большая часть этого также является сгенерированным кодом (включая документы), который не помогает пользователю. Давайте теперь рассмотрим основные шаблоны во всех различных API Google, которые могут помочь нам лучше понять клиентскую библиотеку для навигации и более эффективного ее использования.

Независимо от того, какой API вы решите использовать, все они имеют одну общую черту — способ создания объекта API и выполнения запроса:

Независимо от того, хотите ли вы вызвать Gmail API или любой другой, вы всегда будете создавать сервис, используя build функцию из googleapiclient.discovery, указав имя API, версию и ранее созданные учетные данные. Затем, используя возвращенный объект service, вы можете вызвать любую из функций этого API. Поскольку это сгенерированный код, вы не получите автозаполнение, поэтому лучший способ узнать, какие у вас есть варианты, — перейти на страницу документации. URL-адреса немного сложно найти, хотя, как правило, вы можете просмотреть https://googleapis.github.io/google-api-python-client/docs/dyn/, чтобы найти группу API и методы, которые вам нужны. Так, например, для вышеупомянутого service.users().messages() вы должны пойти здесь.

Наконец, не забудьте вызвать метод .execute(), иначе реального ответа вы не получите. Говоря об этом, ответ будет просто JSON в форме словаря Python, который вам нужно будет пройти, чтобы получить нужные данные. Чтобы узнать, какие поля вы можете ожидать, взгляните на сгенерированные выше документы, которые включают образец объекты ответа.

Построение цепочки методов на основе вышеупомянутого документа API работает хорошо, когда вам нужно выяснить отдельные аргументы одного метода, но может быть неудобно, когда вы пытаетесь ориентироваться или изучать параметры API в целом. Для этого вам лучше поискать справку по REST API, например, для Gmail. Просматривая его, вы быстро заметите, что он следует той же структуре, что и цепочка методов Python (.users().messages().list):

Пинать шины

Теперь, когда мы знаем, как перемещаться по API и вызывать его конечные точки, давайте проверим его шины и посмотрим, что могут сделать для нас все различные API Google.

Мы уже коснулись Gmail API, так что пока мы там, мы можем взглянуть еще на пару его методов:

В приведенном выше фрагменте показано, как мы можем отправить электронное письмо из нашей учетной записи, вошедшей в систему. Это делается путем создания объекта сообщения, который затем кодируется в base64 и передается в .send(...) с использованием аргумента body. Также обратите внимание, что мы использовали "me" в качестве значения для userId — это специальное значение, которое идентифицирует вошедшего в систему пользователя.

Допустим, у вас есть куча писем с вложениями, которые вы хотите извлечь для резервного копирования или дальнейшей обработки. Вы можете использовать Gmail API для захвата этих вложений:

Здесь мы предполагаем, что у вас уже есть сообщения и их идентификаторы. Мы используем этот message_info для запроса к API объекта сообщения. Затем мы перебираем части полезной нагрузки сообщения в поисках частей, которые ссылаются на вложение, то есть частей с непустым атрибутом filename. Затем мы запрашиваем у API каждое вложение, используя его идентификатор, найденный в части сообщения. Возвращаемые данные вложения имеют кодировку base64, здесь мы предполагаем, что это данные в виде открытого текста, но это могут быть PDF, изображения и т. д.

Gmail API — один из самых обширных API, с ним можно делать гораздо больше, поэтому обязательно ознакомьтесь с его Справочником по API.

Переходим от Gmail — другим популярным сервисом Google является Диск, давайте посмотрим, как мы можем искать и скачивать из него файлы:

Мы используем метод .files().list() для поиска файлов. Для облегчения поиска мы указываем запрос в аргументе q в формате query_term operator values — в данном случае mimeType соответствует query_term, = соответствует operator, а 'image/png' соответствует values. Этот запрос гарантирует, что мы получаем только файлы с типом MIME image/png. Запросов можно построить очень много, полный список доступен в документах. В нашем поиске мы также указываем аргумент fields, который указывает API возвращать только идентификатор и имя файлов вместо полной полезной нагрузки.

После того, как мы получим список файлов из API, мы используем .files().get_media для получения метаданных файла, затем мы используем эту информацию для создания объекта downloader, с помощью которого мы загружаем фактический файл. Наконец, мы берем загруженные данные и записываем их в файл.

Помимо управления файлами, Google Drive API также необходим при использовании других API. Например, если вы хотите получить доступ к своим Google Формам, вам нужно использовать Drive API для их поиска:

Для поиска форм мы используем тот же метод .files().list, что и для поиска изображений, с той лишь разницей, что мы изменили аргумент q для поиска Google Forms.

Затем мы можем использовать возвращенную информацию для обработки наших форм, например, для получения всех ответов формы. Обратите внимание, что в этом примере мы указали static_discovery как False, потому что в настоящее время документ статического обнаружения не является частью клиентской библиотеки Python, поэтому нам нужно получить его из Интернета, иначе мы получим исключение UnknownApiNameOrVersion.

Приведенный выше пример также демонстрирует разбиение на страницы с использованием list_next после первоначального вызова list. Это удобно, потому что нам не нужно иметь дело с «токенами следующей страницы», хранящимися в объекте ответа, вместо этого мы просто передаем объекты запроса и ответа методу list_next и позволяем библиотеке обрабатывать все остальное.

Еще один API, который вы, возможно, захотите проверить, — это API фотографий, однако для его работы требуется немного больше усилий:

Как и в случае с Forms API, с Photos API нам также нужно указать static_discovery как False. Однако с этим есть больше проблем - если вы попытаетесь найти его в сгенерированном справочнике по API, упомянутом ранее, его там просто нет. Это потому, что он еще не опубликован, как упоминалось в этом Выпуске GitHub, поэтому тем временем, если мы хотим увидеть, какие методы нам доступны, нам нужно немного покопаться в частных атрибутах, как показано выше.

Хотя это не совсем удобно, этот API все же можно использовать, например, для загрузки изображений в альбом:

Мы начинаем с создания образца альбома, в который мы будем загружать наши изображения — это необходимо, потому что вам разрешено загружать изображения только в альбомы, созданные вашим приложением. После этого мы загрузим изображение, что представляет собой двухэтапный процесс: сначала мы должны загрузить байты изображения, а затем связать загруженные данные с изображением.

На первом этапе мы должны использовать необработанный REST API, отправляя данные изображения в конечную точку Photos API uploads. После этого мы создаем тело запроса, используя идентификатор альбома, имя изображения и токен загрузки, который был возвращен при загрузке необработанных данных, а затем отправляем его в API с помощью метода batchCreate. В этом примере мы загрузили только одно изображение, но вы можете загружать несколько изображений, используя один вызов batchCreate, передавая несколько элементов в запись newMediaItems в теле запроса.

Возвращаясь к API Google Workspace, давайте также рассмотрим API Календаря. Допустим, мы хотим получать уведомления всякий раз, когда в нашем календаре создается новое событие:

С точки зрения API календаря все, что нам нужно сделать, — это настроить канал, по которому будет происходить событие. Мы делаем это, вызывая .events().watch() с телом, содержащим идентификатор, адрес и срок действия канала (время жизни). Адрес здесь должен быть HTTPS-сайтом в Интернете (не localhost). Во время разработки самый простой способ настроить это — использовать такой сервис, как ngrok, который будет перенаправлять запрос на ваш localhost.

После того, как вы настроили переадресацию (с помощью ngrok или любого другого инструмента), вы должны увидеть приходящий запрос HTTP POST, в котором вы можете начать обработку. Пример запроса может выглядеть так:

Последний API, который мы рассмотрим, — это Fact-Checking Tools API, который мы можем использовать для проверки/опровержения заявлений практически о чем угодно:

Этот немного отличается от предыдущих. Ранее мы использовали только OAuth для аутентификации, однако API инструментов проверки фактов является общедоступным API и не требует доступа/авторизации к пользовательским данным, поэтому можно использовать базовую аутентификацию по ключу API. Чтобы получить ключ Google Cloud API, следуйте инструкции здесь.

Еще одна новая вещь, которую мы также демонстрируем в приведенном выше примере, — это использование пакетных запросов — вместо прямых отдельных вызовов .claims().search() здесь мы создаем пакет, используя new_batch_http_request, и добавляем в него все нужные поисковые запросы. При добавлении запросов в пакет мы также предоставляем функцию callback, которая вызывается после выполнения этих конкретных запросов. В этом случае функция обратного вызова — print_claim_review — обрабатывает ответ, печатая исходное утверждение, которое мы искали, вместе с его текстовым рейтингом.

Такая пакетная обработка, вероятно, не имеет смысла, если вы делаете всего пару запросов, как в приведенном выше фрагменте, но может повысить производительность за счет минимизации накладных расходов HTTP-запросов, если вам нужно сделать тысячи вызовов API.

Заключение

В этой статье я попытался описать большинство обычных рабочих процессов и концепций, таких как пакетная обработка, разбиение на страницы, поиск или аутентификация, с которыми вы можете столкнуться при работе с API Google. Однако это не исчерпывающее руководство по всему, что с ними можно сделать, поэтому обязательно ознакомьтесь с другими ресурсами, такими как Примеры клиента API Python или Примеры и фрагменты Google Workspace. Кроме того, для любого серьезного приложения вы обязательно должны также изучить тестирование, в документации клиента API есть раздел о моках.

Наконец, существует множество других API, которые не были рассмотрены в этой статье. Некоторые из них, которые стоит изучить, это API перевода, Речь в текст или API маршрутов (карты), которые включают бесплатный уровень.

Эта статья изначально была опубликована на martinheinz.dev

Стань участником и читай все истории на Medium. Ваш членский взнос напрямую поддерживает меня и других писателей, которых вы читаете. Вы также получите полный доступ ко всем статьям на Medium.



Вам также может понравиться…