Rest api python что это
Полноценный REST API для перфекционистов за 5 минут
Врачи говорят, что это взаимосвязано, мол перфекционизм — это стремление к совершенству, а простота позволяет подобраться к этому мифическому совершенству. Чем проще решение, тем меньше ошибок можно допустить, вот я и подсел. Я не стал с ними спорить и вместо того, что бы искать виновников моей истории, решил с этим жить и постараться повысить качество этой самой жизни.
Мир вокруг не идеален, сложную вещь сделать простой – невероятно сложно, поэтому всё чрезмерно усложнено. Людям нравится чувствовать себя профессионалами, поэтому они оперируют сложными терминами, когда в этом нет необходимости, так они ощущают свою значимость и заполняют пустоту, которая образовалась из-за страха потерянного времени.
Почему я должен постоянно вспоминать о том, общался я с этим человеком или нет? Мы уже перешли на ты? Я пишу какое-то коммерческое предложение и мне надо «Выкнуть» или это ответ на рядовое письмо и достаточно простого «вы». Почему мне постоянно надо расстраиваться, когда мне с порога совершенно незнакомый человек начинает «тыкать», как будто я его друг с курилки?
Я принципиально всем «выкаю» с маленькой буквы и я убеждён, что это имеет свою цену. Наверняка есть люди, которым не нравится, что их назвали с маленькой буквы и они не ответят на моё письмо.
Так зачем эти сложности?
Когда я упомянул про повышение качества жизни, я имел ввиду некоторые правила, которые помогают быстро принимать решения и не жалеть об этом. Например, я не использую сложные вещи постоянно, не общаюсь с людьми, которым нравится всё усложнять. Если вещь, которой вы пользуетесь каждый день – сложна, то это значит только то, что ей не уделили достаточно внимания. Если человек вам не может объяснить даже трудную для понимания тему простым языком, значит, он сам не до конца понимает о чём говорит.
Есть ещё кое-что, что имеет не менее важное значение – время. Время – бесценный ресурс, а выражение «Время — деньги» из уст умных людей вызывает у меня улыбку с разочарованием (выглядишь как идиот и чувствуешь себя так же). Я до сих пор не знаю ни одного миллиардера, которому деньги помогли прожить дольше других людей.
Введение
Речь пойдёт об инструменте, который позволит вам построить полноценный и простой в использовании REST API за минимальное количество времени. Называется он – Python Eve.
К сожалению в Интернете очень много инструкций на эту тему, но все они вводят в заблуждение. Начинающие разработчики, начитавшись подобных статей, думают, что REST API это GET/POST/PUT/DELETE. Заказчики думают, что это дело пары часов. А когда они встречаются вместе, происходят магия в виде Express.js/Mongoose/Passport и ещё кучи хлама, который течёт и временами блокирует event-loop. Всё это запускается с помощью какого-нибудь supervisor, потому что иногда падает и надо как-то перезапускать.
И всё бы ничего, но вчера у меня состоялся разговор с хабра-пользователем, который предложил воспользоваться «Express.js, MongoDB, Mongoose, Passport, отладчиком WebStorm’a и головой на плечах«. Похожие разговоры случались часто, поэтому я решил написать эту статью и «отсылать» ссылкой на неё.
Полноценный REST API?
Речь не только о реализации архитектурного стиля REST API, но и о протоколе HTTP, о валидации и кэшировании, о HATEOAS (wikipedia), о котором, похоже, вообще предпочитают не вспоминать. Затем нам понадобится фильтрация результатов и сортировка, постраничная навигация и частичное обновление записей. Потом мы задумаемся о целостности данных и условных запросах. Наверняка нам понадобится аутентификация, возможно захотим отображать данные не только в JSON, но и в XML. Это ещё про версионность и вложенные записи я не упомянул. Затем, как это обычно бывает, какой-то #$%$%^ начнёт долбить в наш могучий API с тяжёлым запросом и нам понадобится ограничить частоту запросов.
Даже если представить, что разработкой такого API займётся невероятно крутой разработчик с 3-мя мониторами, отладчиком WebStorm’a и головой на плечах, он затратит на это не просто много времени, а очень много. Поддержка кодовой базы будет обходиться дорого, а внедрение новых функций будет долгим.
Но мы с вами простоту – любим, а время – уважаем. Так приступим же!
Установка
Это обычный python-пакет, поэтому устанавливается он стандартным способом:
Если вас интересуют альтернативные методы установки, можете заглянуть в официальную документацию.
Быстрый старт
Перед тем, как мы начнём «творить» магию, нам понадобится база данных MongoDB. Если у вас её нет, вы можете воспользоваться любым бесплатным сервисом, например MongoLab. Регистрация займёт не больше минуты. После регистрации создайте базу данных и пользователя для этой базы.
Теперь давайте напишем минимальную версию нашего REST API. Для начала создадим главный файл run.py со следующим содержимым:
Теперь нам надо создать файл настроек settings.py:
На мой взгляд здесь всё достаточно просто и вопросов возникнуть не должно. Если это не так – добро пожаловать в комментарии. Полный список параметров конфигурации вы можете глянуть в документации.
Всё готово, запускаем:
Прелюдия
Вы уже подумали, что сейчас мы начнём безбожно «curlить», но я вынужден вас разочаровать. Мы, со свойственным нам перфекционизмом, воспользуемся инструментом автора, который обладает чувством прекрасного:
Инструмент называется HTTPie и ставится в один клик одну команду:
Игрища и забавы
HTTPie вызывается командой «http«. Для того, что бы отправить GET запрос к нашему API, выполним:
Благодаря HATEOAS мы видим, что у нас есть 2 ресурса: users и groups. Заглянем внутрь:
Давайте создадим пользователя johndoe:
Первое, на что стоит обратить внимание, это на нашу команду:
HTTPie увидел, что мы отправляем параметр username и превратил его в JSON:
Затем отправил нашему API методом POST. Давайте обратим внимание на ошибки:
Мы видим сразу весь список ошибок валидации и это здорово. Исправим их и выполним запрос повторно:
Ну вот, мы только что успешно создали нового пользователя. Давайте проверим так ли это:
Нет никаких сомнений, что это так. Настало время попробовать перезаписать (обратите внимание, не отредактировать, а перезаписать) пользователя. Делается это с помощью метода PUT, который надо указать явно (если не указать, будет выполнен POST):
Упс, ошибка. Я выше упоминал о целостности данных. Дело в том, что может произойти ситуация, в которой кто-то уже изменил запись, которую хотите поменять вы. И когда вы её отредактируете, то будете думать, что изменили одну запись, но на самом деле уже совсем другую.
Для того, что бы мы в такой ситуации не оказались, используется идентификатор ETag. В двух словах — это уникальный идентификатор, который генерируется Eve при каждом изменении записи. Используя этот идентификатор мы можем сказать нашему API, что хотим изменить запись только определённой версии и если она с тех пор была отредактирована, то наши изменения выполнены не будут. Делается это с помощью условного запроса с HTTP заголовком «If-Match«:
Обратите внимание каким образом мы передали HTTP заголовок HTTPie. Это не единственное, для чего может использоваться идентификатор ETag и условные запросы. Я здесь не буду останавливаться на этом, но советую вам ознакомиться с этой темой, если вы этого ещё не сделали.
Настало время создать новую группу. Для начала попробуем создать группу с несуществующим пользователем:
И действительно, пользователя с таким _id не существует. Обратите внимание как мы передаём список пользователей:
Подробнее вы можете почитать в официальной документации к HTTPie, которая такая же качественная, как и сам инструмент.
На этот раз мы укажем правильный _id:
«Усё добра», как говорила моя прабабушка. Проверим:
Прабабушка оказалась бы права. На этом можно было бы закончить, но мы поступим иначе.
Получим группу с пользователями, которые в неё входят, в развёрнутом виде:
Попросим тоже самое в XML:
Попробуем изменить только имя нашего пользователя (без полной перезаписи). Для этого воспользуемся HTTP методом PATCH:
Что сказала бы бабуля?
«Усё добра». Мне так понравилось, что я бы создавал пользователей пачками:
Найдём пользователя «John Doe» по его имени:
Отсортируем пользователей по их логину в обратном порядке:
Ну и наконец-то удалим всех пользователей:
Я бы не стал включать данную возможность в production. Указывается это в параметре RESOURCE_METHODS (стоит убрать из списка DELETE):
Заключение
Мы рассмотрели не все возможности Eve, но даже c учётом этого – получили законченный вариант REST API.
В данной статье я хотел обратить внимание на то, что настоящий RESTful сервис это гораздо больше, чем пара модулей для Node.js и в большинстве случаев нет необходимости разрабатывать такие вещи с нуля, а тем более писать статьи о том, как это сделать за один час. Достаточно взглянуть на историю развития проекта, что бы лишний раз убедиться в том, что пары часов/дней/недель недостаточно даже для хорошей команды.
Nicola Iarocci, автор Eve, создал прекрасный инструмент для быстрого развёртывания REST API, уделил этому достаточно внимания и сохранил простоту использования.
Работа с REST API на Python
Введение
В этой статье вы узнаете как писать запросы к REST API на Python 3.
Прежде чем что-то устанавливать убедитесь, что вы знакомы с работой в виртуальном окружении Python.
Прочитать об этом можно в статье «Виртуальные окружения в Python»
Подготовка
Активируйте ваше виртуальное окружение и установите requests командой
Изучите список установленных модулей
requests подтягивает за собой requests, certifi, chardet, idna, urllib3
Проверить куда установился requests в этом окружении можно командой
Name: requests Version: 2.24.0 Summary: Python HTTP for Humans. Home-page: https://requests.readthedocs.io Author: Kenneth Reitz Author-email: me@kennethreitz.org License: Apache 2.0 Location: /home/andrei/python/virtualenvs/answerit_env/lib/python3.8/site-packages Requires: certifi, chardet, urllib3, idna Required-by:
Чтобы сделать GET запрос достаточно импортировать requests и выполнить requests. get
Создайте файл rdemo.py следующего содержания:
import requests r = requests. get (‘https://xkcd.com/353/’) print (r)
Запустите скрипт командой
Если получили 200 значит всё хорошо. Изменим наш код, чтобы узнать, какие действия мы можем произвести с объектом
dir(r) выдаст список доступных атрибутов и методов
import requests r = requests. get (‘https://topbicycle.ru/b/stels_pilot_950_md_26.php’) print (dir(r))
[‘__attrs__’, ‘__bool__’, ‘__class__’, ‘__delattr__’, ‘__dict__’, ‘__dir__’, ‘__doc__’, ‘__enter__’, ‘__eq__’, ‘__exit__’, ‘__format__’, ‘__ge__’, ‘__getattribute__’, ‘__getstate__’, ‘__gt__’, ‘__hash__’, ‘__init__’, ‘__init_subclass__’, ‘__iter__’, ‘__le__’, ‘__lt__’, ‘__module__’, ‘__ne__’, ‘__new__’, ‘__nonzero__’, ‘__reduce__’, ‘__reduce_ex__’, ‘__repr__’, ‘__setattr__’, ‘__setstate__’, ‘__sizeof__’, ‘__str__’, ‘__subclasshook__’, ‘__weakref__’, ‘_content’, ‘_content_consumed’, ‘_next’, ‘apparent_encoding’, ‘close’, ‘connection’, ‘content’, ‘cookies’, ‘elapsed’, ‘encoding’, ‘headers’, ‘history’, ‘is_permanent_redirect’, ‘is_redirect’, ‘iter_content’, ‘iter_lines’, ‘json’, ‘links’, ‘next’, ‘ok’, ‘raise_for_status’, ‘raw’, ‘reason’, ‘request’, ‘status_code’, ‘text’, ‘url’]
Более подробную информацию можно получить заменив dir(r) на help(r)
Из этого документа можно узнать http статус содержится в атрибуте status_code
import requests r = requests. get (‘https://topbicycle.ru/b/stels_pilot_950_md_26.php’) print (r.status_code)
Если всё прошло успешно, то получите
ok вернёт True если ответ не 4XX или 5XX
headers возвращает заголовок ответа
Также из этого документа можно узнать что text возвращает содержимое ответа в формате unicode а content содержимое ответа в байтах
import requests r = requests. get (‘https://xkcd.com/353/’) print («content:») print («——«) print (r.content) print («——«) print («text:») print («——«) print (r.text)
Обычно content используют для работы с изображениями
Перейдите на TopBicycle.ru и найдите первое фото велосипеда.
Скопируйте его url
Теперь измените код так, чтобы сохранить изображение в файл
import requests r = requests. get ( https://topbicycle.ru/b/img/stels_pilot_950_MD_26.jpg» ) with open(«bike.jpg», «wb») as f: f.write(r.content)
Если всё прошло успешно, в вашей папке появится следующее фото
GET с параметрами
Для проверки ваших навыков работы с REST API можно воспользоваться сайтом httpbin.org
Он будет возвращать вам обратно ваш запрос.
Изменим код rdemo.py :
Параметры можно записать сразу после url за знаком вопроса, но надёжнее оформить их в виде отдельного словаря (dictionary).
Чтобы отправить и проверить POST запрос внесите небольшие изменения в код.
Очевидно, что GET нужно заменить на POST, также params нужно заменить на data
import requests payload = <'website': 'heihei.ru', 'established': 2018>r = requests. post (‘https://httpbin.org/post’, data= payload) print (f»url:
В этом случае данные записываются в словарь и к ним очень легко обращаться.
Обратите внимание на «form» данные, которые были переданы возвращаются в этом поле.
Изменим код так, чтобы на экран выводились только эти данные
import requests payload = <'website': 'heihei.ru', 'established': 2018>r = requests. post (‘https://httpbin.org/post’, data= payload) r_dict = r. json () print (r_dict[‘form’])
Всё аналогично POST просто замените post на put
Рассмотрим пример, в котором нужно передать в теле запроса json, а также использовать имеющийся токен для авторизации
Обратите внимание на следующие моменты
Обработка ответа
Рассмотрим приёмы, которые пригодятся при работе с полученными данными
Предположим, получены данные в формате json.
Нужно извлечь из них токен, который хранится в access_token
Чтобы его получить, воспользуйтесь методом json() который возвращает словарь ( ).
И из этого словаря получите токен по ключевому слову access_token
r_dict = r.json() access_token = r_dict[ «access_token» ]
json.dumps
Если вы хотите сразу же изучить полученный json можно воспользоваться методом dumps()
Если вы получили не json а dict, json.dumps нужно использовать так:
sort_keys делать не обязательно. Это я для примера показываю, что можно отсортировтаь ключевые слова.
Вытащить часть ответа
Часто интерес бывает не весь ответ, а только часть. О том как её грамотно выделить из ответа читайте в статье
Аутентификация
Рассмотрим базовую аутентификацию на сайте httpbin
Придумайте любое имя пользоватлея и пароль к нему.
Я придумал andrey с паролем heihei
Введите ваши логин и пароль
Убедитесь, что аутентификация прошла успешно
Теперь проделаем такую же аутентификацию с помощью Python
Создайте файл auth_demo.py со следующим кодом
Ответ совпадает с тем что мы уже получали в браузере
Выполните такой же запрос, но с неправильным паролем. Убедитесь в том, что text ничего не содержит. Замените print (r.text) на print (r) и убедитесь, что полученный объект это
Задержка
Часто бывает нужно ограничить время ожидания ответа. Это можно сделать с помощью параметра timeout
Создайте файл timeout_demo.py следующего содержания
import requests r = requests. get (‘https://httpbin.org/delay/1’, timeout= 3) print (r)
Задержка равна одной секунде. А ждать ответ можно до трёх секунд.
Измените код так, чтобы ответ приходил заведомо позже чем наш таймаут в три секунды.
import requests r = requests. get (‘https://httpbin.org/delay/7’, timeout= 3) print (r)
Задержка равна семи секундам. А ждать ответ можно по-прежнему только до трёх секунд.
Traceback (most recent call last): File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 421, in _make_request six.raise_from(e, None) File » «, line 3, in raise_from File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 416, in _make_request httplib_response = conn.getresponse() File «/usr/lib/python3.8/http/client.py», line 1347, in getresponse response.begin() File «/usr/lib/python3.8/http/client.py», line 307, in begin version, status, reason = self._read_status() File «/usr/lib/python3.8/http/client.py», line 268, in _read_status line = str(self.fp.readline(_MAXLINE + 1), «iso-8859-1») File «/usr/lib/python3.8/socket.py», line 669, in readinto return self._sock.recv_into(b) File «/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py», line 326, in recv_into raise timeout(«The read operation timed out») socket.timeout: The read operation timed out During handling of the above exception, another exception occurred: Traceback (most recent call last): File «/usr/lib/python3/dist-packages/requests/adapters.py», line 439, in send resp = conn.urlopen( File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 719, in urlopen retries = retries.increment( File «/usr/lib/python3/dist-packages/urllib3/util/retry.py», line 400, in increment raise six.reraise(type(error), error, _stacktrace) File «/usr/lib/python3/dist-packages/six.py», line 703, in reraise raise value File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 665, in urlopen httplib_response = self._make_request( File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 423, in _make_request self._raise_timeout(err=e, url=url, timeout_value=read_timeout) File «/usr/lib/python3/dist-packages/urllib3/connectionpool.py», line 330, in _raise_timeout raise ReadTimeoutError( urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host=’httpbin.org’, port=443): Read timed out. (read timeout=3) During handling of the above exception, another exception occurred: Traceback (most recent call last): File «timeout_demo.py», line 4, in r = requests.get(‘https://httpbin.org/delay/7’, timeout=3) File «/usr/lib/python3/dist-packages/requests/api.py», line 75, in get return request(‘get’, url, params=params, **kwargs) File «/usr/lib/python3/dist-packages/requests/api.py», line 60, in request return session.request(method=method, url=url, **kwargs) File «/usr/lib/python3/dist-packages/requests/sessions.py», line 533, in request resp = self.send(prep, **send_kwargs) File «/usr/lib/python3/dist-packages/requests/sessions.py», line 646, in send r = adapter.send(request, **kwargs) File «/usr/lib/python3/dist-packages/requests/adapters.py», line 529, in send raise ReadTimeout(e, request=request) requests.exceptions.ReadTimeout: HTTPSConnectionPool(host=’httpbin.org’, port=443): Read timed out. (read timeout=3)
✨ Python и API: превосходное комбо для автоматизации работы с публичными данными
Leo Matyushkin
Многие ежедневно используемые приложения и системы имеют свой API. От очень простых и обыденных вещей, таких как проверка погоды по утрам, до более захватывающих, вроде лент Instagram, TikTok или Twitter. Во всех современных приложениях API-интерфейсы играют центральную роль.
В этом туториале мы детально рассмотрим:
К концу прохождения туториала вы сможете использовать Python для большинства общедоступных API. Если вы разработчик, знание того, как использовать API-интерфейсы с Python, поможет в интеграции вашей работы со сторонними приложениями.
Знакомство с API
Аббревиатура API соответствует английскому application programming interface — программный интерфейс приложения. По сути, API действует как коммуникационный уровень или интерфейс, который позволяет различным системам взаимодействовать друг с другом без необходимости точно понимать, что делает каждая из систем.
API-интерфейсы имеют разные формы. Это может быть API операционной системы, используемый для включения камеры и микрофона для присоединения к звонку Zoom. Или это могут быть веб-API, используемые для действий, ориентированных на веб, таких как лайки фотографий в Instagram или получение последних твитов.
Независимо от типа, все API-интерфейсы работают приблизительно одинаково. Обычно программа-клиент запрашивает информацию или данные, а API возвращает ответ в соответствии с тем, что мы запросили. Каждый раз, когда мы открываем Twitter или прокручиваем ленту Instagram, приложение делает запрос к API и просто отображает ответ с учетом дизайна программы.
В этом руководстве мы подробно остановимся на высокоуровневых веб-API, которые обмениваются информацией между сетями.
SOAP vs REST vs GraphQL
В конце 1990-х и начале 2000-х годов две разные модели дизайна API стали нормой для публичного доступа к данным:
Сегодня распространение также получает GraphQL — созданный Facebook гибкий язык API-запросов. Хотя GraphQL находится на подъеме и внедряется крупными компаниями, включая GitHub и Shopify, большинство общедоступных API-интерфейсов это REST API. Поэтому в рамках руководства мы ограничимся именно REST-подходом и тем, как взаимодействовать с такими API с помощью Python.
requests и API
Установите библиотеку любым удобным вам способом, например, с помощью pip:
Чтобы следовать примерам кода из руководства, убедитесь, что вы используете Python не ниже 3.8 и версию библиотеки requests не ниже 2.22.0.
Обращение к API с помощью Python
Достаточно разговоров — пора сделать первый вызов API! Мы вызовем популярный API для генерации случайных пользовательских данных. Единственное, что нужно знать для начала работы с API — по какому URL-адресу его вызывать. В этом примере это https://randomuser.me/api/, и вот самый простой вызов API, с которого мы и начнем:
Конечные точки и ресурсы
Как мы видели выше, первое, что нужно знать для использования API, — это базовый URL-адрес API. Вот так выглядят базовые URL-адреса нескольких известных провайдеров API:
Попытавшись открыть любую из приведенных ссылок, вы заметите, что большинство из них возвращает ошибку или запрашивает учетные данные. Многие API-интерфейсы требуют аутентификации для определения прав доступа.
Сделаем запрос к интерфейсу TheDogAPI, аналогичный приведенному выше:
При вызове базового URL-адреса мы получаем сообщение, в котором говорится, что мы обратились к Dog API. Базовый URL здесь используется для получения информации об API, а не реальных данных.
Конечная точка (endpoint) — это часть URL-адреса, указывающая, какой ресурс мы хотим получить. Хорошо документированные API-интерфейсы содержат справочник по API, описывающий конечные точки и ресурсы API, а также способы их использования.
Есть такой справочник и у TheDogAPI. Попробуем обратиться к конечной точке, предоставляющей характеристики пород:
Вуаля, мы получили список пород!
Если вы больше любите кошек, аналогичный API есть и для мурлыкающих питомцев:
Request и Response
Все взаимодействия между клиентом (в нашем случае консолью Python) и API разделены на запрос ( request ) и ответ ( response ):
Снова обратившись к TheDogAPI, мы можем немного подробнее рассмотреть, что именно находится внутри объектов request и response :
В приведенном примере показаны некоторые из наиболее важных атрибутов, доступных для объектов запроса и ответа.
Коды состояний HTTP
Код состояния — одна из наиболее важных частей ответа API, которая сообщает, закончился ли запрос успешно, были ли найдены данные, нужна ли информация об учетной записи и т. д.
Со временем вы без посторонней помощи научитесь распознавать различные коды состояний. Но пока приведем список наиболее распространенных:
Код состояния | Описание |
200 OK | Запрос успешно выполнен. |
201 Created | Запрос принят и создан ресурс. |
400 Bad Request | Запрос неверен или отсутствует некоторая информация. |
401 Unauthorized | Запрос требует дополнительных прав. |
404 Not Found | Запрошенный ресурс не существует. |
405 Method Not Allowed | Конечная точка не поддерживает этот метод HTTP. |
500 Internal Server Error | Ошибка на стороне сервера. |
Теперь отправим запрос, содержащий в пути намеренно сделанную ошибку:
Заголовки HTTP
HTTP-заголовки (headers) используются для определения нескольких параметров, управляющих запросами и ответами:
HTTP Header | Описание |
Accept | Какой тип контента может принять клиент |
Content-Type | Какой тип контента в ответе сервера |
User-Agent | Какое программное обеспечение клиент использует для связи с сервером |
Server | Какое программное обеспечение сервер использует для связи с клиентом |
Authentication | Кто вызывает API и с какими учетными данными |
Чтобы проверить заголовки ответа, можно использовать response.headers :
В этом случае мы не определяем какие-либо конкретные заголовки при отправке запроса, поэтому возвращаются заголовки по умолчанию.
Пользовательские заголовки
X-Request-Id находится среди других заголовков, которые по умолчанию идут с любым запросом API.
Content-Type
В наши дни большинство API-интерфейсов используют в качестве типа контента по умолчанию JSON.
Вернувшись к одному из предыдущих примеров использования TheDogAPI, мы заметим, что заголовок Content-Type определен как application/json :
Помимо типа содержимого (в данном случае application/json ), заголовок может возвращать кодировку контента.
Вы можете столкнуться и c API, возвращающими XML или мультимедиа, например, изображения или видео.
Заголовок Content-Type позволяет узнать, как обрабатывать ответ и что делать с содержимым ответа.
Содержание ответа
Как видите, после выполнения response.json() мы получаем словарь, который можно использовать так же, как любой другой словарь в Python.
Методы HTTP
При вызове API существует несколько различных методов, которые мы можем использовать, чтобы указать, какое действие хотим выполнить. Например, если мы хотим получить некоторые данные, мы используем метод GET, а если нужно создать некоторые данные — метод POST.
Вот список наиболее распространенных методов и их типичных вариантов использования:
HTTP-метод | Описание | Метод requests |
POST | Создает новый ресурс. | requests.post() |
GET | Считывает имеющийся ресурс. | requests.get() |
PUT | Обновляет существующий ресурс. | requests.put() |
DELETE | Удаляет ресурс. | requests.delete() |
Эти четыре метода также называют CRUD-операциями, поскольку они позволяют создавать (create), читать (read), обновлять (update) и удалять (delete) ресурсы.
Большинство этих запросов вернут код состояния 405 (Method Not Allowed). Не все конечные точки поддерживают методы POST, PUT или DELETE. Действительно, большинство общедоступных API разрешают только запросы GET и не позволяют создавать или изменять существующие данные без авторизации.
Параметры запроса
Иногда при вызове API можно получить тонну данных, которые в массе своей не нужны. При вызове конечной точки TheDogAPI/breeds мы получаем всю информацию о каждой породе, но вполне вероятно, что нам достаточно лишь небольшой части данных для одного подвида собак. Тут пригождаются параметры запроса!
Наверняка вы уже сталкивались с параметрами запроса при просмотре веб-страниц в Интернете. При просмотре видео на YouTube у вас есть URL-адрес вида https://www.youtube.com/watch?v=aL5GK2LVMWI. Параметр v= в URL-адресе и есть параметр запроса. Обычно он идет после базового URL-адреса и конечной точки.
Тот же URL-адрес YouTube, указанный выше, с несколькими параметрами запроса будет выглядеть следующим образом: https://www.youtube.com/watch?v=aL5GK2LVMWI&t=75.
В мире API параметры запроса используются в качестве фильтров. Они отправляются вместе с запросом API и позволяют сузить поле для поиска.
Возвратимся к API генератора случайных пользователей:
Предположим, что мы хотим привлечь женскую аудиторию из Германии, и в качестве примеров необходимо сгенерировать соответствующих пользователей. Согласно документации, для нашей задачи можно использовать параметры запроса gender= и nat= :
Используя параметры запроса, мы можем получать более конкретные данные от API, адаптируя взаимодействие с API к нашим потребностям.
Чтобы избежать повторного создания URL-адреса, мы можем передавать параметры запроса в виде атрибута-словаря params :
Изучение продвинутых концепций API
Теперь, когда у нас есть представление об основах использования API с Python, есть несколько более сложных тем, которые стоит хотя бы кратко затронуть: аутентификация, пагинация и ограничения по времени.
Аутенфикация
Хотя многие API бесплатны и полностью общедоступны, аутентификация обычно существенно расширяет права доступа. Существует множество API, требующих аутентификации, например:
Подходы к аутентификации варьируются от очень простых, например, использования ключей API или базовой аутентификации, до гораздо более сложных и безопасных методов, таких как OAuth.
Ключи API
Самый распространенный подход к аутентификации — это ключ API (API key). Эти ключи используются для идентификации вас как пользователя или клиента API, а также для отслеживания использования вами интерфейса. Ключи API обычно отправляются как заголовок запроса или как параметр запроса.
Всё идет нормально. Нам удалось сделать аутентифицированный запрос к API NASA и получить ответ 200 OK.
Взглянем поближе на объект Response и попробуем извлечь из него несколько изображений:
OAuth: начало работы
Другой распространенный стандарт аутентификации API — это OAuth. Это очень обширная тема, поэтому мы коснемся только самых основ.
Когда приложение или платформа позволяет зарегистрироваться или войти с помощью другого ресурса, например, Google или Facebook, поток аутенфикации обычно использует OAuth.
Вот пошаговое описание того, что происходит, когда мы нажимаем в приложении Spotify кнопку «Продолжить с Facebook»:
При прохождении четвертого шага Facebook предоставит Spotify специальные учетные данные — токен доступа ( access_token ), который можно многократно использовать для получения информации. Этот токен входа в Facebook действителен в течение шестидесяти дней, но у других приложений могут быть другие сроки действия.
С технической точки зрения вот что нам нужно знать при использовании API с использованием OAuth:
Существуют различные вариации этого процесса, но большинство потоков OAuth содержат шаги, аналогичные описанным. Давайте попробуем OAuth на примере GitHub API.
OAuth: практический пример
Как мы видели выше, первое, с чего стоит начать — создать приложение. В документации GitHub есть отличное пошаговое объяснение, как это сделать. Чтобы не разворачивать отдельный сервер, в качестве адреса для перенаправления можно использовать адрес https://httpbin.org/anything. Эта веб-страница просто выводит все, что получает на входе.
Создадим приложение, скопируем и вставим Client_ID и Client_Secret вместе с указанным URL для переадресации в файл Python, который назовем github.py :
У нас есть все необходимые переменные, теперь нужно создать ссылку для перенаправления пользователя на его учетную запись GitHub, как описано в документации GitHub:
Следующим шагом в процессе авторизации является обмен полученного кода на токен доступа. Опять же, следуя инструкциям в документации GitHub, мы можем создать для этого метод:
Здесь мы делаем POST-запрос для обмена кода на токен доступа. В запросе мы должны отправить CLIENT_SECRET и код, чтобы GitHub проверил, что код сгенерирован нашим приложением. После этого GitHub API генерирует и возвращает токен доступа.
Мы можем добавить в свой файл следующий код и попробовать его запустить:
Мы должны получить действующий токен доступа, который можно использовать для вызовов API GitHub от имени аутентифицированного пользователя.
Попробуем добавить следующий код, чтобы получить свой профиль пользователя с помощью User API и распечатать свое имя, имя пользователя и количество приватных репозиториев:
Осталось только собрать все вместе и попробовать:
В результате запуска скрипта мы получим примерно такой результат:
Большинство API-интерфейсов, использующих OAuth, ведут себя одинаково, поэтому достаточно один раз разобраться во всех процессах.
Пагинация
За пересылку большого массива данных между клиентами и сервером приходится платить пропускной способностью. Для снижения нагрузки на сервер API-интерфейсы обычно используют пагинацию — разбиение выдаваемой информации на страницы.
Например, всякий раз, когда мы переходим на страницу вопросов в Stack Overflow, внизу страницы есть ряд чисел, соответствующих страницам пагинации:
В API пагинация обычно обрабатывается с помощью двух параметров запроса:
Конкретные имена параметров запроса могут сильно различаться в зависимости от выбора разработчиков API. Некоторые провайдеры API могут также использовать HTTP-заголовки или JSON для возврата текущих фильтров разбивки на страницы.
Снова воспользуемся GitHub API. Параметр per_page= определяет количество возвращаемых элементов, а page= позволяет разбивать результат на отдельные страницы. Пример использования параметров:
Ограничение скорости
Учитывая, что рассматриваемые API-интерфейсы являются общедоступными и могут использоваться кем угодно, ими пытаются злоупотреблять люди с плохими намерениями. Чтобы предотвратить такие атаки, используется метод, называемый ограничением скорости ( rate limit ). API ограничивает количество запросов, которые пользователи могут сделать за определенный период. В случае превышения лимита API-интерфейсы временно блокируют IP-адрес или API-ключ.
Некоторые API, такие как GitHub, даже включают в заголовки дополнительную информацию о текущем ограничении скорости и количестве оставшихся запросов. Это очень помогает избежать превышения установленного лимита.
Использование API с помощью Python: практические примеры
Теперь, когда мы поэкспериментировали с несколькими API, можно объединить полученные знания с помощью еще нескольких практических примеров.
Запрос наиболее популярных сейчас гифок
Как насчет создания небольшого скрипта, который извлекает три самых популярных сейчас GIF-файла с веб-сайта GIPHY? Начните с получения API-ключа:
Ключ API используем в GIPHY API:
Запуск этого кода выведет структурированный список со ссылками на гифки:
Получение подтвержденных случаев COVID-19 в каждой стране
API сайта, отслеживающего случаи заболевания COVID-19, не требует аутентификации. В следующем примере мы получим общее количество подтвержденных случаев до предыдущего дня:
В этом примере мы получаем общее количество подтвержденных случаев для всей страны. Однако вы также можете просмотреть документацию и получить данные для конкретного города.
Поиск в Google Книгах
Воспользуемся API Google Книг для поиска информации об интересующей нас книге. Вот простой фрагмент кода для поиска названия книги Моби Дик во всем каталоге с выдачей трех первых записей:
Вы можете использовать свои знания OAuth и создать приложение, хранящее записи о книгах, которые читаете или хотите прочитать.
Заключение
Есть множество других вещей, которые вы ещё узнаете об API: другие заголовки, типы контента, методы аутентификации и так далее. Однако концепции и методы, которые мы рассмотрели в этом руководстве, позволят достаточно быстро разобраться и провзаимодействовать с помощью Python с любыми API.
Напоследок приведем список агрегаторов ссылок на публичные API, которые вы можете использовать в собственных проектах:
На Python создают прикладные приложения, пишут тесты и бэкенд веб-приложений, автоматизируют задачи в системном администрировании, его используют в нейронных сетях и анализе больших данных. Язык можно изучить самостоятельно, но на это придется потратить немало времени. Если вы хотите быстро понять основы программирования на Python, обратите внимание на онлайн-курс «Библиотеки программиста». За 30 уроков (15 теоретических и 15 практических занятий) под руководством практикующих экспертов вы не только изучите основы синтаксиса, но и освоите две интегрированные среды разработки (PyCharm и Jupyter Notebook), работу со словарями, парсинг веб-страниц, создание ботов для Telegram и Instagram, тестирование кода и даже анализ данных. Чтобы процесс обучения стал более интересным и комфортным, студенты получат от нас обратную связь. Кураторы и преподаватели курса ответят на все вопросы по теме лекций и практических занятий.