Как сделать свой api на python

Обновлено: 05.07.2024

Некоторое время назад мы научились работать из языка Python с PostgreSQL. Следующим логическим (для меня, во всяком случае) шагом было бы научиться делать REST API, и вперед, можно клепать микросервисы налево и направо! Обычно при изучении очередного микро веб-фреймворка я привожу пример с телефонной книгой. Но он мне уже надоел, так что напишем приложение для хранения тем к выпуску подкаста.

Схема базы данных будет очень простой:

-- заливается командой `psql (аргументы)
CREATE TABLE themes ( id SERIAL PRIMARY KEY , title TEXT , url TEXT ) ;

Файл requirements.txt (см заметку про virtualenv) у меня получился таким:

Наконец, код самого приложения:

import postgresql
import flask
import json

app = flask. Flask ( __name__ )


def db_conn ( ) :
return postgresql. open ( 'pq://eax@localhost/eax' )


def to_json ( data ) :
return json . dumps ( data ) + " \n "


def resp ( code , data ) :
return flask. Response (
status = code ,
mimetype = "application/json" ,
response = to_json ( data )
)


def theme_validate ( ) :
errors = [ ]
json = flask. request . get_json ( )
if json is None :
errors. append (
"No JSON sent. Did you forget to set Content-Type header" +
" to application/json?" )
return ( None , errors )

for field_name in [ 'title' , 'url' ] :
if type ( json . get ( field_name ) ) is not str :
errors. append (
"Field '<>' is missing or is not a string" . format (
field_name ) )

return ( json , errors )


def affected_num_to_code ( cnt ) :
code = 200
if cnt == 0 :
code = 404
return code


@ app. route ( '/' )
def root ( ) :
return flask. redirect ( '/api/1.0/themes' )


@ app. errorhandler ( 404 )
def page_not_found ( e ) :
return resp ( 400 , < >)


@ app. errorhandler ( 405 )
def page_not_found ( e ) :
return resp ( 405 , < >)


@ app. route ( '/api/1.0/themes' , methods = [ 'GET' ] )
def get_themes ( ) :
with db_conn ( ) as db:
tuples = db. query ( "SELECT id, title, url FROM themes" )
themes = [ ]
for ( id , title , url ) in tuples:
themes. append ( < "id" : id , "title" : title , "url" : url >)
return resp ( 200 , < "themes" : themes >)

with db_conn ( ) as db:
insert = db. prepare (
"INSERT INTO themes (title, url) VALUES ($1, $2) " +
"RETURNING id" )
[ ( theme_id , ) ] = insert ( json [ 'title' ] , json [ 'url' ] )
return resp ( 200 , < "theme_id" : theme_id >)

with db_conn ( ) as db:
update = db. prepare (
"UPDATE themes SET title = $2, url = $3 WHERE > )
( _ , cnt ) = update ( theme_id , json [ 'title' ] , json [ 'url' ] )
return resp ( affected_num_to_code ( cnt ) , < >)


@ app. route ( '/api/1.0/themes/ ' , methods = [ 'DELETE' ] )
def delete_theme ( theme_id ) :
with db_conn ( ) as db:
delete = db. prepare ( "DELETE FROM themes WHERE > )
( _ , cnt ) = delete ( theme_id )
return resp ( affected_num_to_code ( cnt ) , < >)

Как видите, все предельно просто и понятно, ничего лишнего. Вот такой код я называю выразительным, красивым и декларативным. А не тот, что пытаются впарить некоторые любители линз и scalaz :)

Пример взаимодействия с сервисом:

В качестве домашнего задания можете проверить, как приложение обрабатывает ошибки, а также какие коды и заголовки оно возвращает в ответах.

А с использованием каких фреймворков и/или библиотек вы пишите REST-сервисы? А также, чем парсите конфиги, пишите логи, и как все это хозяйство упаковываете?

В прошлый раз мы, чтобы получить данные из кода, копировали HTML-элемент вручную в среду разработки. Сегодня мы попробуем сделать это с помощью модуля request. Он не встроенный, его нужно установить отдельно, как и BeautifulSoup


Работа с API


Application Programming Interface (API) — интерфейс, созданный специально для того, чтобы машине (компьютеру) было проще считать нужную информацию с сайта. Т.е. можно спарсить код, где вставляется погода с помощью регулярных выражений или BeautifulSoup. но лучше (и правильней) сделать это с помощью API

С помощью API удобно получать именно данные, а не какой-либо участок кода с ними. В API меньше кода — всё собрано в одном месте. Нет нужды парсить это регулярными выражениями. И API всегда будет работать, даже если источник поменял на сайте HTML-код.

import requests
import json

Результат (здесь температура указана в кельвинах)


Как запустить свой сервер?

Поднять свой локальный сервер можно с помощью библиотеки flask. Её тоже нужно отдельно устанавливать — она не встроенная.

from flask import Flask

Результат — сервер запущен:


Аргументы в web-запросах

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

Введение

В этой статье рассказывается, как написать простое клиентское приложение Python, в котором реализованы основные этапы работы с Management API:

  1. Извлечение нового токена авторизации OAuth 2.0.
  2. Создание нового экземпляра авторизованного объекта службы.
  3. Извлечение данных конфигурации с помощью запросов к API.
  4. Работа с ответами.
  5. Обработка ошибок.

Перед началом работы

Перед началом работы выполните следующие действия.

Получите библиотеку. Установите клиентскую библиотеку Google API для Python, в которой реализованы все функции и контейнеры для работы с API.

Зарегистрируйте приложение. Все запросы к Management API из вашего приложения должны быть разрешены пользователем, прошедшим аутентификацию. В этом примере для приложения, установленного в Google Developers Console, используется токен OAuth 2.0. Подробнее.

После настройки этих зависимостей любое приложение, использующее клиентскую библиотеку Python, в том числе и наш пример, будет готово к работе. Далее приведенный пример будет разобран подробно.

Авторизация запросов

Чтобы просмотреть данные в интерфейсе Google Analytics, вам необходимо войти в систему. Точно так же для доступа к данным пользователей Google Analytics вашему приложению потребуется разрешение. В API версии 3.0 авторизация осуществляется с использованием токенов OAuth 2.0.

Чтобы реализовать этот процесс, зарегистрируйте новый проект в Google Developers Console и настройте в нем протокол OAuth 2.0 для установленных приложений. При регистрации вы получаете два объекта, необходимых для работы с API:

  • уникальный идентификатор клиента ( clientId );
  • секретный ключ клиента ( clientSecret ).

Примечание. Подробнее об авторизации запросов OAuth 2.0 в других средах, включая веб-приложения на стороне сервера или клиента, читайте в разделе Авторизация запросов.

При первом запуске примера из этой статьи появляется запрос, в котором пользователь должен разрешить доступ к своим данным, указав соответствующий URL. После этого пользователь получает код авторизации, который необходимо предоставить приложению. На основе этого кода приложение получает токены доступа и обновления OAuth 2.0 .

Токен доступа используется для доступа к пользовательским данным из API и действует неограниченное время для большей эффективности. Как только токен становится недействительным, API возвращает код статуса 401 . Чтобы получить новый токен доступа, в этом примере (как и в любом рабочем приложении) используется токен обновления.

Чтобы упростить авторизацию, в клиентской библиотеке Python реализованы контейнеры, обеспечивающие работу с процессом OAuth 2.0, а также многократное использование токенов, сохраненных на диске. В следующем коде реализован процесс авторизации OAuth 2.0 для установленных приложений.

При выполнении этот код запрашивает у пользователя разрешение на доступ к его данным (в этом случае в объекте TOKEN_FILE_NAME сохраняется новый токен) или считывает существующий токен из объекта учетных данных ( credentials ) в файле.

На основе полученного объекта credentials создается экземпляр объекта службы для работы с API.

Создание нового экземпляра объекта службы

В клиентской библиотеке Python реализован объект службы, позволяющий выполнять запросы к Management API и анализировать возвращаемые ответы.

После того, как был создан экземпляр объекта службы, приложение может выполнять авторизованные запросы к Management API.

Выполнение запросов к API и обработка ошибок

Приложение использует созданный объект службы Analytics для выполнения всех запросов к Management API. Все пять поддерживаемых типов запросов к API достаточно просты и возвращают список объектов одного типа для указанного пользователя, прошедшего аутентификацию. Список называется коллекцией, а содержащиеся в нем объекты – ресурсами.

В разделе Начало работы описывается применяемая иерархия типов: объектом верхнего уровня является аккаунт, который может содержать коллекцию дочерних веб-ресурсов и т. д. Приложение в этом примере выполняет запросы к API с использованием ранее созданного экземпляра объекта службы Analytics , который обеспечивает сбор данных по иерархии. Так, в следующем коде вызов к API возвращает список аккаунтов пользователей.

Обработка ошибок

Объект службы Analytics может вызывать исключения двух типов:

Работа с аккаунтами

Аккаунт Google Analytics располагается на верхнем уровне иерархии Management API и не имеет родительских объектов. Дочерними для него являются ресурсы типа Веб-ресурс. Чтобы запросить список всех доступных пользователю аккаунтов Google Analytics, используйте объект службы Analytics , экземпляр которого был создан в предыдущем примере.

Результаты метода list записываются в объект accounts_list и поэтапно обрабатываются, как показано в следующем примере. О том, как получить список ресурсов для объекта Account , читайте здесь.

Идентификатор аккаунта, возвращаемый методом get('id') в этом примере, используется в качестве параметра для последующих запросов, которые показаны далее.

Работа с веб-ресурсами

Веб-ресурсы располагаются на втором уровне в иерархии аккаунта Google Analytics. Каждый веб-ресурс имеет один родительский аккаунт и одно или несколько дочерних представлений (профилей).

Чтобы запросить список веб-ресурсов для одного из аккаунтов пользователя, в приложении используется объект service , в который передается идентификатор нужного аккаунта (параметр accountId метода list ). В следующем примере запрашивается список всех веб-ресурсов для аккаунта с идентификатором 12345.

Метод list для веб-ресурса принимает обязательный параметр accountId , указывающий на аккаунт, ресурсы которого требуется извлечь. Если нужно извлечь ресурсы для всех аккаунтов пользователя, присвойте значение ~all параметру accountId , как показано в следующем примере.

Результаты метода list записываются в объект webproperties_list и поэтапно обрабатываются, как показано в следующем примере. О том, как получить список ресурсов для объекта Webproperty читайте здесь.

Идентификатор веб-ресурса, возвращаемый методом get('id') в этом примере, используется в качестве параметра для последующих запросов, которые показаны далее.

Работа с представлениями (профилями)

Представление (профиль) располагается на третьем уровне в иерархии аккаунта Google Analytics. Каждое представление (профиль) имеет один родительский веб-ресурс и коллекцию с любым количеством дочерних целей.

Идентификатор представления (профиля) при доступе к фиду данных указывается в параметре tableId и необходим для извлечения данных отчета.

Чтобы получить список представлений (профилей), доступных пользователю, в приложении вызывается соответствующий метод list , который принимает обязательные параметры accountId и webPropertyId .

Чтобы запросить представления (профили) для конкретных аккаунта и веб-ресурса, укажите нужные идентификаторы, как показано в следующем примере.

Чтобы запросить представления (профили) для всех веб-ресурсов указанного аккаунта, необходимо присвоить параметру webPropertyId значение "~all". В следующем примере возвращается список представлений (профилей) для всех веб-ресурсов аккаунта с идентификатором 12345.

Чтобы запросить все доступные пользователю представления (профили), присвойте обоим параметрам идентификаторов значение ~all . Следующий код возвращает список представлений (профилей) для всех веб-ресурсов всех аккаунтов пользователя.

Примечание. Если в запросе к Management API указано значение ~all для параметра родительского объекта, задать идентификатор конкретного дочернего объекта невозможно. По этой причине следующий запрос будет недействительным.

Результаты выполнения метода list записываются в объект profiles_list и поэтапно обрабатываются, как показано в следующем примере. О том, как получить список свойств для объекта profile , читайте здесь.

Идентификатор представления (профиля), возвращаемый методом get('id') в этом примере, используется в качестве параметра для ресурса типа "Цель" в следующем разделе. В реальных приложениях этот идентификатор передается в параметре ids в запросе к фиду данных в Core Reporting API.

Работа с целями

Цель находится на четвертом, нижнем, уровне иерархии аккаунта Google Analytics и не имеет дочерних объектов. У каждой цели в иерархии есть одно родительское представление (профиль). В Management API предоставляются данные о названии, значении, типе цели и ее статусе (активна или нет).

В этом примере с помощью соответствующего метода list запрашивается список целей для объекта службы Analytics . Этот метод принимает обязательные параметры accountId , webPropertyId и profileId .

Чтобы запросить цели для отдельного представления (профиля), необходимо указать идентификаторы родительских аккаунта, веб-ресурса и представления (профиля), как показано в следующем примере.

Чтобы запросить все цели для всех представлений (профилей) пользователя, используйте подстановочный знак ~all , как в следующем коде.

Примечание. Если в запросе к Management API указано значение ~all для параметра родительского объекта, задать идентификатор конкретного дочернего объекта невозможно.

В следующем примере в методе list передается конкретный идентификатор profileID , равный 420, однако параметру webPropertyId присвоено значение ~all . Соответственно, такой запрос будет недействительным.

Результаты метода list для целей записываются в объект goals_list и поэтапно обрабатываются, как показано в следующем примере. Список свойств для ресурса типа "Цель" вы найдете здесь.

Свойства цели

Цель Google Analytics может иметь один из четырех типов, которые описываются в этом разделе. К ним относятся:

  • URL_DESTINATION;
  • VISIT_TIME_ON_SITE;
  • VISIT_NUM_PAGES;
  • EVENT.

Каждому типу цели соответствует свой набор данных.

Цель URL_DESTINATION

Эта цель достигается, когда пользователь переходит на одну или несколько страниц, указанных в ее определении. Вы можете задать последовательность шагов для достижения каждой цели. Management API возвращает все настроенные шаги и поэтапно обрабатывает их, как показано в следующем примере.

Цели VISIT_TIME_ON_SITE

Эта цель достигается, если пользователь проводит на сайте определенное время в течение одного сеанса.

Цель VISIT_NUM_PAGES

Эта цель достигается, если пользователь в течение сеанса посещает заданное количество страниц.

Цель EVENT

Эта цель может достигаться при соблюдении различных условий, которые описываются здесь.

Management API возвращает список со всеми вариантами условий, значения которых зависят от типа (свойство type ) цели. Для целей VALUE используются свойства comparisonType и comparisonValue , а для целей CATEGORY , ACTION и LABEL – свойства matchType и expression .

Форматы и значения свойств для всех четырех типов ресурса Goal описываются здесь.

Работа с расширенными сегментами

Расширенный сегмент находится на верхнем уровне в иерархии Management API и не имеет ни родительских, ни дочерних объектов.

Подробнее. Помимо стандартных расширенных сегментов, пользователи Google Analytics могут создавать и сохранять собственные с помощью веб-интерфейса Google Analytics. Все сегменты, доступные прошедшему аутентификацию пользователю, возвращаются с помощью соответствующего метода list .

Все сегменты, доступные прошедшему аутентификацию пользователю, возвращаются с помощью соответствующего метода list . Чтобы запросить список стандартных и специальных сегментов пользователя с помощью метода list для объекта службы Analytics , в этом примере применяется следующий код.

Результаты метода list записываются в объект segments_list и поэтапно обрабатываются, как показано в следующем коде. Список свойств для ресурса типа "Сегмент" вы найдете здесь.

Подробнее о расширенных сегментах. В реальных приложениях значение, возвращаемое методом get('id') , используется в качестве параметра segment для фида данных Core Reporting API. Отрицательные идентификаторы соответствуют стандартным сегментам, а положительные – специальным, которые были определены для прошедшего аутентификацию пользователя.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Это руководство познакомит вас с веб-API и научит вас, как использовать библиотеку Python запросов для получения и обновления информации в веб-API. В качестве рабочего примера вы также узнаете, как взаимодействовать с API Twitter.

Введение в веб-API

Вот некоторые из наиболее распространенных API, которые позволяют разработчикам интегрировать и использовать свою инфраструктуру:

  1. API Google
  2. API Twitter
  3. Amazon API
  4. API Facebook

Одна из наиболее важных причин использования API в отличие от других статических источников данных заключается в том, что он работает в режиме реального времени. Например, API Twitter, который мы собираемся использовать, будет получать данные в реальном времени из социальной сети.

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

Использование библиотеки запросов

Установить запросы

В своем терминале введите:

Чтобы проверить успешность установки, введите следующую команду в интерпретаторе Python или в терминале:

Если ошибок нет, установка прошла успешно.

Как получить информацию из веб-API

Метод GET используется для получения информации с веб-сервера. Давайте посмотрим, как сделать запрос GET, чтобы получить общедоступную временную шкалу GitHub.

Мы используем переменную req для хранения ответа на наш запрос.

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

Читайте также: