Учебное пособие Python API: Начало работы с API

В этом уроке по Python API мы узнаем, как получать данные для проектов по науке о данных. В Интернете существуют миллионы API, которые обеспечивают доступ к данным. Такие сайты, как Reddit, Twitter и Facebook, предлагают определенные данные через свои API.
Чтобы использовать API, вы отправляете запрос на удаленный веб-сервер и извлекаете нужные данные.
Но зачем использовать API вместо статического набора данных CSV, который можно загрузить из Интернета? API полезны в следующих случаях:
  • Данные быстро меняются. Примером могут служить данные о цене акций. Нет смысла регенерировать набор данных и загружать его каждую минуту – это сильно загрузит полосу пропускания и будет довольно медленным.
  • Вам нужен небольшой фрагмент гораздо большего набора данных. Комментарии Reddit являются одним из примеров. Что делать, если вы хотите просто оставить свои комментарии на Reddit? Нет смысла загружать всю базу данных Reddit, а затем фильтровать только ваши собственные комментарии.
  • Существует многократное вычисление. Spotify имеет API, который может подсказать вам жанр музыкального произведения. Вы можете теоретически создать свой собственный классификатор и использовать его для вычисления музыкальных категорий, но у вас никогда не будет такого количества данных, как у Spotify.
В случаях, подобных приведенным выше, API является правильным решением. В этом блоге мы будем запрашивать простой API для получения данных о Международной космической станции (МКС).
Об этом руководстве по Python API
Это руководство основано на части нашего интерактивного курса по API и Webscraping в Python, к которому вы можете приступить бесплатно.
В этом руководстве предполагается, что вы знакомы с некоторыми основами работы с данными в Python. Если это не так, вы можете попробовать наш бесплатный курс по его основам.
Что такое API?
API или интерфейс прикладного программирования — это сервер, который вы можете использовать для извлечения и отправки данных с использованием кода. API-интерфейсы чаще всего используются для извлечения данных, и это будет основной темой этого урока для начинающих.
Когда мы хотим получить данные из API, нам нужно сделать запрос. Запросы используются во всем Интернете. Например, когда вы посетили это пост, ваш веб-браузер отправил запрос на веб-сервер Dataquest, который ответил содержимым этой веб-страницы
Запросы API работают точно так же — вы отправляете запрос данных на сервер API, и он отвечает на ваш запрос.
Создание запросов API в Python
Чтобы работать с API в Python, нам нужны инструменты, которые будут создавать эти запросы. В Python самой распространенной библиотекой для создания запросов и работы с API является библиотека запросов. Библиотека запросов не является частью стандартной библиотеки Python, поэтому для начала работы вам необходимо установить ее.
Если вы используете pip для управления своими пакетами Python, вы можете устанавливать запросы, используя следующую команду:
pip install requests
Если вы используете conda, вам понадобится следующая команда:
conda install requests
После того, как вы установили библиотеку, вам нужно будет ее импортировать. Давайте начнем с этого важного шага:

# no pec


import requests
Теперь, когда мы установили и импортировали библиотеку запросов, давайте начнем ее использовать.
Создание нашего первого запроса API
Есть много разных типов запросов. Наиболее часто используемым является GET-запрос. Он используется для извлечения данных. Поскольку мы просто будем работать с поиском данных, мы сосредоточимся на том, чтобы делать запросы на получение.
Когда мы делаем запрос, ответ от API сопровождается кодом ответа, который сообщает нам, был ли наш запрос успешным. Коды ответов важны, потому что они немедленно сообщают нам, если что-то пошло не так.
Чтобы сделать запрос «GET», мы будем использовать функцию requests.get() function, для которой требуется один аргумент — URL-адрес, на который мы хотим сделать запрос. Начнем с того, что сделаем запрос к конечной точке API, которой не существует, чтобы мы смогли увидеть, как выглядит этот код ответа.

import requests


import requests
response = requests.get("http://api.open-notify.org/this-api-doesnt-exist")
Функция get() возвращает объект response. Мы можем использовать атрибут response.status_code , чтобы получить код состояния для нашего запроса:

import requests
response = requests.get("http://api.open-notify.org/this-api-doesnt-exist")


print(response.status_code)
404
Код состояния «404» может быть вам знаком — это код состояния, который сервер возвращает, если не может найти запрошенный нами файл. В этом случае мы просили this-api-doesnt-exist, которого (сюрприз, сюрприз) не существует!
Давайте узнаем немного больше о распространенных кодах состояния.
Коды состояния API
Коды состояния возвращаются при каждом запросе к веб-серверу. Коды состояния указывают информацию о том, что произошло с запросом. Вот некоторые коды, которые относятся к запросам GET:
• 200: все прошло хорошо, и результат был возвращен (если есть).
• 301: сервер перенаправляет вас на другую конечную точку. Это может произойти, когда компания меняет доменные имена или меняется имя конечной точки.
• 400: сервер считает, что вы сделали неверный запрос. Это может произойти, если вы, помимо прочего, не отправляете верные данные.
• 401: сервер считает, что вы не прошли проверку подлинности. Для многих API требуются учетные данные для входа, поэтому это происходит в том случае, когда вы не отправляете правильные учетные данные для доступа к API.
Вы можете заметить, что все коды состояния, начинающиеся с «4», указывают на какую-то ошибку. Первое число кодов состояния указывает на их классификацию. Это полезно — вы можете знать, что если ваш код состояния начинается с «2», он был успешным, а если он начинается с «4» или «5», произошла ошибка. Если вас заинтересовала данная тема, вы можете прочитать больше о кодах статуса
Документация по API 
Чтобы мы создали успешный запрос при работе с API важно обращаться к документации. Вначале документация может показаться пугающей, но чем больше вы будете использовать ее, тем вам будет легче.
Мы будем работать с Open Notify API, который предоставляет доступ к данным о международной космической станции. Это отличный API для обучения, потому что у него очень простой дизайн и не требуется аутентификация. Мы научим вас, как использовать API, требующий аутентификации, в следующем посте.
Часто на конкретном сервере будет доступно несколько API. Каждый из этих API обычно называют конечными точками. Первой конечной точкой, которую мы будем использовать, является http://api.open-notify.org/astros.json, которая возвращает данные об астронавтах, которые находятся в космосе в настоящее время.
Если вы нажмете на ссылку выше, чтобы посмотреть документацию по этой конечной точке, вы увидите, что в ней написано, что этот API не требует ввода данных. Это делает его простым API для нас, с которого можно начать. Начнем с того, что сделаем запрос GET к конечной точке, используя библиотеку запросов:

import requests


response = requests.get("http://api.open-notify.org/astros.json")
print(response.status_code)
200
Мы получили код «200», который говорит нам, что наш запрос был успешным. Документация говорит нам, что ответ API мы получим в формате JSON. В следующем разделе мы изучим JSON, но сначала давайте воспользуемся методом response.json() method, чтобы увидеть данные, которые мы получили от API:

import requests
response = requests.get("http://api.open-notify.org/astros.json")


print(response.json())

{
  "message": "success",
  "people": [
    {
      "name": "Alexey Ovchinin",
      "craft": "ISS"
    },
    {
      "name": "Nick Hague",
      "craft": "ISS"
    },
    {
      "name": "Christina Koch",
      "craft": "ISS"
    },
    {
      "name": "Alexander Skvortsov",
      "craft": "ISS"
    },
    {
      "name": "Luca Parmitano",
      "craft": "ISS"
    },
    {
      "name": "Andrew Morgan",
      "craft": "ISS"
    }
  ],
  "number": 6
}

Работа с данными JSON в Python
JSON (JavaScript Object Notation) — это язык API. JSON — это способ кодирования структур данных, который обеспечивает их удобочитаемость на компьютерах. JSON — это основной формат, в котором данные передаются туда и обратно в API, и большинство серверов API отправляют свои ответы в формате JSON.
Вы могли заметить, что вывод JSON, который мы получили от API, выглядел так, как будто он содержит словари, списки, строки и целые числа Python. Вы можете представлять JSON как комбинацию этих объектов, представленных в виде строк. Давайте рассмотрим простой пример:
Python имеет отличную поддержку JSON с пакетом json. Пакет json является частью стандартной библиотеки, поэтому нам не нужно ничего устанавливать для его использования. Мы можем конвертировать списки и словари в JSON, а также конвертировать строки в списки и словари. В случае наших данных ISS Pass это словарь, закодированный в строку в формате JSON:
  • json.dumps() — принимает объект Python и преобразует (сбрасывает) его в строку.
  • json.loads() — принимает строку JSON и преобразует (загружает) ее в объект Python.
Функция dumps() особенно полезна, так как мы можем использовать ее для печати отформатированной строки, что облегчает понимание вывода JSON, как на диаграмме, которую мы видели выше:

import requests
response = requests.get("http://api.open-notify.org/astros.json")


import json
def jprint(obj):
# create a formatted string of the Python JSON object< text = json.dumps(obj, sort_keys=True, indent=4) print(text) jprint(response.json())
    
{
    "message": "success",
    "number": 9,
    "people": [
        {
            "craft": "ISS",
            "name": "Alexey Ovchinin"
        },
        {
            "craft": "ISS",
            "name": "Nick Hague"
        },
        {
            "craft": "ISS",
            "name": "Christina Koch"
        },
        {
            "craft": "ISS",
            "name": "Alexander Skvortsov"
        },
        {
            "craft": "ISS",
            "name": "Luca Parmitano"
        },
        {
            "craft": "ISS",
            "name": "Andrew Morgan"
        },
        {
            "craft": "ISS",
            "name": "Oleg Skripochka"
        },
        {
            "craft": "ISS",
            "name": "Jessica Meir"
        },
        {
            "craft": "ISS",
            "name": "Hazzaa Ali Almansoori"
        }
    ]
}
    
  
Сразу же мы можем проще понять структуру данных - мы видим, что в настоящее время в космосе находятся шесть человек, а их имена существуют в виде словарей внутри списка.
Если мы сравним это с документацией для конечной точки, то увидим, что это соответствует указанному выводу для конечной точки.
Использование API с параметрами запроса
Конечная точка http://api.open-notify.org/astros.json, которую мы использовали ранее, не принимает никаких параметров. Мы просто отправляем запрос GET, и API отправляет данные о количестве людей, находящихся в настоящее время в космосе.
Однако очень часто имеется конечная точка API, которая требует от нас указания параметров. Примером служит конечная точка http://api.open-notify.org/iss-pass.json. Эта конечная точка сообщит нам в следующий раз, что международная космическая станция пройдет над определенным местом на земле.
Если мы посмотрим на документацию, в ней указаны обязательные параметры lat (широты) и long (долготы).
Мы можем сделать это, добавив необязательный ключевой аргумент params к нашему запросу. Мы можем создать словарь с этими параметрами, а затем передать их в функцию requests.get. Вот как будет выглядеть наш словарь при использовании координат для Нью-Йорка:

parameters = {
"lat": 40.71,
"lon": -74
}
Мы также можем сделать то же самое напрямую, добавив параметры непосредственно в URL. вот так: http://api.open-notify.org/iss-pass.json?lat=40.71&lon=-74.
Почти всегда предпочтительнее настроить параметры в качестве словаря, потому что requests  заботится о некоторых возникающих вещах, таких как, например, правильное форматирование параметров запроса, и нам не нужно беспокоиться о вставке значений в строку URL.
Давайте сделаем запрос, используя эти координаты, и посмотрим, какой будет ответ.

import requests
import json
def jprint(obj):
# create a formatted string of the Python JSON object< text = json.dumps(obj, sort_keys=True, indent=4) print(text) parameters = { "lat": 40.71, "lon": -74 }


response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
jprint(response.json())
    
{
    "message": "success",
    "request": {
        "altitude": 100,
        "datetime": 1569878531,
        "latitude": 40.71,
        "longitude": -74.0,
        "passes": 5
    },
    "response": [
        {
            "duration": 575,
            "risetime": 1569882047
        },
        {
            "duration": 562,
            "risetime": 1569887921
        },
        {
            "duration": 632,
            "risetime": 1569893735
        },
        {
            "duration": 620,
            "risetime": 1569899543
        },
        {
            "duration": 142,
            "risetime": 1569905532
        }
    ]
}
    
  
Понимание времени прохождения
Ответ JSON соответствует тому, что указано в документации:
  • словарь с тремя ключами
  • Третий ключ, response, содержит список времен прохождения
  • Каждое время прохождения - это словарь с ключами risetime (время начала прохождения) и duration ключей.
Давайте извлечем время прохода из нашего объекта JSON:

import requests
import json
def jprint(obj):
# create a formatted string of the Python JSON object< text = json.dumps(obj, sort_keys=True, indent=4) print(text) parameters = { "lat": 40.71, "lon": -74 } response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)


pass_times = response.json()['response']
jprint(pass_times)
    
    
  
  
[
    {
        "duration": 575,
        "risetime": 1569882047
    },
    {
        "duration": 562,
        "risetime": 1569887921
    },
    {
        "duration": 632,
        "risetime": 1569893735
    },
    {
        "duration": 620,
        "risetime": 1569899543
    },
    {
        "duration": 142,
        "risetime": 1569905532
    }
]
  
Далее мы будем использовать цикл для извлечения только пяти значений risetime:

import requests
response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
pass_times = response.json()['response']


risetimes = []
for d in pass_times:
time = d['risetime']
risetimes.append(time)
print(risetimes)
[1568082479, 1568088118, 1568093944, 1568099831, 1568105674]
Эти времена трудно понять - они представлены в формате, известном как отметка времени или эпоха. По сути, время измеряется в количестве секунд с 1 января 1970 года. Мы можем использовать метод Python datetime.fromtimestamp(), чтобы преобразовать их в более понятные времена:

import requests
response = requests.get("http://api.open-notify.org/iss-pass.json", params=parameters)
pass_times = response.json()['response']


from datetime import datetime
times = []
for rt in risetimes:
time = datetime.fromtimestamp(rt)
times.append(time)
print(time)
    
2019-09-09 21:27:59
2019-09-09 23:01:58
2019-09-10 00:39:04
2019-09-10 02:17:11
2019-09-10 03:54:34
    
  
Похоже, МКС часто проходит над Нью-Йорком - следующие пять раз происходят в течение семи часов!
Python API Tutorial: следующие шаги
Из этого урока мы узнали:
  • Что такое API
  • Типы запросов и коды ответов
  • Как сделать запрос на получение
  • Как сделать запрос с параметрами
  • Как отображать и извлекать данные JSON из API
Эти фундаментальные шаги помогут вам начать работу с API. Помните, что ключом к каждому использованию API было внимательное прочтение документации по API и ее использовании, чтобы понять, какой запрос сделать и какие параметры предоставить.