Баннер мобильный (3) Пройти тест

Как подключиться к API на Python: пошаговая инструкция

Проще, чем кажется

Разбор

23 сентября 2026

Поделиться

Скопировано
Как подключиться к API на Python: пошаговая инструкция

Содержание

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

    Понятие API и его предназначение

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

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

    Самым распространенным типом API являются веб-API, функционирующие через протокол HTTP — тот же, что применяется браузером при загрузке страниц. Когда человек вводит адрес в браузере, тот отправляет HTTP-запрос на сервер, который обрабатывает его и возвращает HTTP-ответ в виде веб-страницы. Веб-API работают аналогично, но часто выдают данные в формате JSON или XML.

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

    • В онлайн-платежах магазины подключают API систем вроде Stripe, PayPal, ЮKassa, чтобы проводить транзакции без собственной банковской инфраструктуры. 
    • Сервисы доставки и такси через API карт (Google Maps, Яндекс Карты) показывают маршруты и местоположение курьеров. 
    • Сайты с помощью API позволяют быстро авторизоваться через учетные записи Google, VK, Яндекс и других сервисов. 
    • Прогноз погоды на смартфоне запрашивается через API метеосервисов (OpenWeatherMap, Open-Meteo). 
    • Магазины синхронизируют заказы с CRM или системами учета (1С, МойСклад) также через API. 
    • Агрегаторы билетов (Авиасейлс, Booking) берут цены и места напрямую из баз авиакомпаний и отелей. 
    • Приложения подключают ИИ-функции через API OpenAI. 
    • Банк отправляет уведомления о транзакциях через API провайдеров (Twilio, МТТ).

    Структура запросов и ответов

    В запросе к API обычно указывают: 

    • URL — адрес ресурса; 
    • HTTP-метод — нужное действие (GET, POST, PUT, PATCH, DELETE); 
    • заголовки — дополнительные сведения (тип содержимого, токены авторизации); 
    • тело запроса — передаваемые данные (для POST, PUT, PATCH).

    Основные методы: 

    • GET — получение данных (список пользователей, информация о товаре); 
    • POST — создание нового ресурса (регистрация, новый пост); 
    • PUT — полное обновление объекта; 
    • PATCH — частичное обновление (изменение пары полей); 
    • DELETE — удаление ресурса (аккаунта, записи).

    Ответ API включает: 

    • код состояния HTTP (числовой результат); 
    • заголовки ответа и тело ответа (обычно в формате JSON или XML). 

    Коды состояния: 

    • 2xx — успех (200, 201); 
    • 3xx — перенаправление (301); 
    • 4xx — ошибка клиента (404, 401); 
    • 5xx — ошибка сервера (500).

    Простые запросы на Python

    В Python есть встроенная библиотека urllib, но работать с ней неудобно из-за громоздкого синтаксиса, сложностей с аутентификацией, отсутствия поддержки современных протоколов и других причин. Основной и самый популярный инструмент для работы с API в Python — это библиотека requests. Она довольно простая и понятная в использовании. Подробнее об этой библиотеке с акцентом на GET-запросы можно прочитать в этой статье. Установить библиотеку можно одной командой:

    pip install requests

    Теперь попробуем создать несколько запросов.

    GET-запрос

    Создадим простой GET-запрос. Для этого воспользуемся сервисом JSONPlaceholder, который имитирует блог с постами и отлично подходит для тестирования работы с API.

    import requests
    
    response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
    
    print(response.status_code)
    print(response.json())

    В первой строке происходит импорт необходимой библиотеки. Далее функция get() отправляет GET-запрос на указанный в виде параметра URL-адрес. Цифра 1 в конце адреса означает, что запрашивается пост с id равным 1. Ответ сервера сохраняется в переменную response. Первый вызов функции print выводит статус-код ответа от сервера, а во втором вызове print метод json() превращает текстовый ответ сервера, который пришел в формате JSON в привычный словарь Python. В консоли получим следующий вывод:

    200
    {'userId': 1, 'id': 1, 'title': 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', 'body': 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto'}

    Можно легко узнать сколько всего постов в блоге, а также вывести заголовок первого поста. Делаем так:

    import requests
    
    response = requests.get("https://jsonplaceholder.typicode.com/posts")
    
    posts = response.json()
    
    print(f"Всего постов: {len(posts)}")
    print(f"Заголовок первого поста: {posts[0]['title']}")

    Обратим внимание, что теперь в конце URL-адреса нет конкретного ID (нет /1). Это значит, что сервер вернет не один объект, а массив (список) всех существующих постов. Далее метод json() превращает JSON-ответ сервера в структуру данных Python. Поскольку сервер вернул массив, переменная posts становится списком (list), внутри которого лежат словари (каждый словарь — это отдельный пост).

    В первом вызове print используем функцию len() для подсчета элементов в списке posts. Программа выведет общее количество полученных постов (на этом сервере их обычно 100). Во втором вызове print обращаемся к самому первому посту в списке (нумерация начинается с нуля) и достаем из этого поста значение по ключу title (заголовок). В итоге получим такой вывод в консоли:

    Всего постов: 100
    Заголовок первого поста: sunt aut facere repellat provident occaecati excepturi optio reprehenderit

    Если необходимо отфильтровать данные, получаемые по запросу, то это можно сделать при помощи параметра params:

    import requests
    
    response = requests.get(
        "https://jsonplaceholder.typicode.com/posts",
        params={"userId": 1}
    )
    
    posts = response.json()
    print(f"Постов пользователя 1: {len(posts)}")

    Здесь библиотека сама построит нужный адрес, который будет выглядеть так:

    https://jsonplaceholder.typicode.com/posts?userId=1

    То есть, как видим, к адресу просто добавился нужный параметр. В результате мы получим количество постов пользователя с идентификатором 1. Вывод в консоли будет такой:

    Постов пользователя 1: 10

    POST-запрос

    Не всегда нужно что-то получать от сервера. Часто приходится отправлять на сервер какие-то данные. Например, вот так можно создать новый пост:

    import requests
    
    new_post = {
        "title": "Первый пост",
        "body": "Привет, мир!",
        "userId": 1
    }
    
    response = requests.post(
        "https://jsonplaceholder.typicode.com/posts",
        json=new_post
    )
    
    print(response.status_code)
    print(response.json())

    В переменной new_post находится содержимое нового поста, который мы хотим добавить на сервер. Запрос на добавление создается при помощи метода post. На вход этого метода подаются адрес, по которому надо добавить пост и, собственно, сам пост. В консоли мы получим код состояния и содержимое добавленного поста с новым id:

    201
    {'title': 'Первый пост', 'body': 'Привет, мир!', 'userId': 1, 'id': 101}

    Запросы PUT и PATCH

    PUT-запрос применяется для полной замены записи. Заменим, например, первый пост в блоге:

    import requests
    
    updated_post = {
        "id": 1,
        "title": "Новый заголовок",
        "body": "Новый текст",
        "userId": 1
    }
    
    response = requests.put(
        "https://jsonplaceholder.typicode.com/posts/1",
        json=updated_post
    )
    
    print(response.status_code)
    print(response.json())

    Для замены поста применяется метод put. На вход этого метода подается адрес этого поста и пост, который придет ему на замену. В консоли получим:

    200
    {'id': 1, 'title': 'Новый заголовок', 'body': 'Новый текст', 'userId': 1}

    Чтобы заменить только какую-то часть записи применяется PATCH-запрос. Заменим, например, заголовок в первом посте:

    import requests
    
    response = requests.patch(
        "https://jsonplaceholder.typicode.com/posts/1",
        json={"title": "Новый заголовок"}
    )
    
    print(response.status_code)
    print(response.json())

    Здесь мы применяем метод patch. На вход метода подается адрес поста, который нужно изменить и новый заголовок к нему. В результате получим следующий вывод в консоли:

    200
    {'userId': 1, 'id': 1, 'title': 'Новый заголовок', 'body': 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto'}

    DELETE-запрос

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

    import requests
    
    response = requests.delete(
        "https://jsonplaceholder.typicode.com/posts/1"
    )
    
    print(response.status_code) 

    Как видим, нужно просто применить метод delete, на вход которого подать адрес поста для удаления. В итоге получим следующий статус-код:

    200

    Значит, удаление прошло успешно.

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

    В реальности работа с API может проходить не очень гладко. Серверы могут быть недоступны, долго отвечать или же попросту может отсутствовать интернет. Чтобы отлавливать все эти события (ошибки), полезно использовать конструкцию try – except, например, таким образом:

    import requests
    
    try:
        response = requests.get("https://jsonplaceholder.typicode.com/posts/1", timeout=5)
        response.raise_for_status()
        data = response.json()
        print(data["title"])
    except requests.exceptions.HTTPError as e:
        print(f"HTTP-ошибка: {e}")
    except requests.exceptions.ConnectionError:
        print("Нет соединения с сервером")
    except requests.exceptions.Timeout:
        print("Сервер не ответил вовремя")
    except Exception as e:
        print(f"Неожиданная ошибка: {e}")

    В создании запроса мы установили таймаут равный 5 секундам. Если сервер не ответит в течение этого времени, запрос будет принудительно прерван. Метод raise_for_status очень важен. По умолчанию библиотека requests не считает ошибкой ответы сервера вроде 404 (Не найдено) или 500 (Ошибка сервера) и продолжает выполнять код. Этот метод принудительно вызывает исключение HTTPError, если статус-код ответа находится в диапазоне 4xx или 5xx. Если все проходит нормально, то в консоль будет выведен заголовок первого поста:

    sunt aut facere repellat provident occaecati excepturi optio reprehenderit

    Если же произойдет какая-то ошибка, то сработает один из блоков except, и в консоль будет выведено соответствующее сообщение. Добавим, например, случайных символов в URL-адрес:

    https://jsonplaceholder45fger.typicode.com/posts/1

    Запустим код и получим такое сообщение:

    https://jsonplaceholder45fger.typicode.com/posts/1

    Работа с пагинацией

    Пагинация — это процесс разделения большого объема информации на отдельные, меньшие по размеру страницы. Многие API отдают данные постранично — например, по 10 записей за раз. Вот так можно пройти по всем страницам списка пользователей на еще одном сервисе с тестовым API ReqRes:

    import requests
    
    base_url = "https://reqres.in/api/users"
    page = 1
    all_users = []
    
    while True:
        response = requests.get(base_url, params={"page": page, "per_page": 6})
        response.raise_for_status()
        data = response.json()
    
        all_users.extend(data["data"])
    
        if page >= data["total_pages"]:
            break
        page += 1
    
    print(f"Всего пользователей: {len(all_users)}")
    for user in all_users:
        print(f"{user['first_name']} {user['last_name']} -- {user['email']}")

    В цикле while создается GET-запрос, у которого кроме URL-адреса есть еще параметр page (счетчик страниц). Этот параметр увеличивается на единицу во время каждой итерации и присоединяется к адресу. Таким образом конструируется ссылка на новую страницу.

    Метод extend() берет список пользователей из текущего ответа сервера и добавляет их в конец общего списка all_users. Цикл завершится, когда значение счетчика станет равным или превысит общее количество страниц total_pages. После запуска в консоли получим такой вывод:

    Всего пользователей: 12
    George Bluth -- george.bluth@reqres.in
    Janet Weaver -- janet.weaver@reqres.in
    Emma Wong -- emma.wong@reqres.in
    Eve Holt -- eve.holt@reqres.in
    Charles Morris -- charles.morris@reqres.in
    Tracey Ramos -- tracey.ramos@reqres.in
    Michael Lawson -- michael.lawson@reqres.in
    Lindsay Ferguson -- lindsay.ferguson@reqres.in
    Tobias Funke -- tobias.funke@reqres.in
    Byron Fields -- byron.fields@reqres.in
    George Edwards -- george.edwards@reqres.in
    Rachel Howell -- rachel.howell@reqres.in

    Авторизация

    Для доступа ко многим API требуется ключ или токен. То есть нужна авторизация. Самый популярный способ авторизации — передать ключ или токен в заголовке Authorization. Вот простой пример GET-запроса с авторизацией:

    import requests
    
    headers = {
        "Authorization": "0123456",
        "Accept": "application/json"
    }
    
    response = requests.get(
        "https://reqres.in/api/users/6",
        headers=headers
    )
    
    print(response.status_code)
    print(response.json())

    В консоли получим данные пользователя с идентификатором 6:

    200
    {'data': {'id': 6, 'email': 'tracey.ramos@reqres.in', 'first_name': 'Tracey', 'last_name': 'Ramos', 'avatar': 'https://reqres.in/img/faces/6-image.jpg'}, 'support': {'url': 'https://benhowdle.im/first-cto-playbook?utm_source=reqres&utm_medium=json&utm_campaign=referral', 'text': 'Become a better CTO. A playbook of painful stories and practical advice from a two-time startup CTO.'}, '_meta': {'powered_by': 'ReqRes', 'docs_url': 'https://app.reqres.in/documentation', 'upgrade_url': 'https://app.reqres.in/upgrade', 'example_url': 'https://app.reqres.in/examples/notes-app', 'variant': 'v1_b', 'message': 'This is a read-only demo endpoint. Sign up to create your own collections with full CRUD and auth.', 'cta': {'label': 'Get started', 'url': 'https://app.reqres.in/upgrade'}, 'context': 'legacy_success'}}

    Авторизация прошла успешно и все данные получены.

    Сессии

    Сессии (Session) позволяют сохранять определенные параметры (например, заголовки, куки) между несколькими запросами к одному и тому же API. То есть можно не прописывать заголовки (headers) каждый раз заново. Также они повторно использует одно и то же TCP-соединение, что ускоряет работу. Пример:

    import requests
    
    session = requests.Session()
    session.headers.update({
        "Authorization": "0123456",
        "Accept": "application/json"
    })
    
    # Первый запрос (ID 1)
    response1 = session.get("https://reqres.in/api/users/1")
    data1 = response1.json()
    print(f"Пользователь 1: {data1['data']['first_name']}")
    
    # Второй запрос (ID 2) -- заголовки подставляются сами
    response2 = session.get("https://reqres.in/api/users/2")
    data2 = response2.json()
    print(f"Пользователь 2: {data2['data']['first_name']}")
    
    session.close()  # закрываем сессию, когда закончили

    В самом начале мы создали сессию посредством requests. Далее передали ей заголовки, а потом уже перешли к созданию запросов с ее помощью. Как видим, теперь get вызывается не для requests, а для session. В конце закрываем сессию методом close. Чтобы сессия закрывалась автоматически, можно использовать with:

    import requests
    
    # Открываем сессию через with (теперь session.close() в конце не нужен)
    with requests.Session() as session:
        session.headers.update({
            "Authorization": "0123456",
            "Accept": "application/json"
        })
    
        # Первый запрос (ID 1)
        response1 = session.get("https://reqres.in/api/users/1")
        data1 = response1.json()
        print(f"Пользователь 1: {data1['data']['first_name']}")
    
        # Второй запрос (ID 2)
        response2 = session.get("https://reqres.in/api/users/2")
        data2 = response2.json()
        print(f"Пользователь 2: {data2['data']['first_name']}")

    И в том и в другом случае в консоли получим следующее:

    Пользователь 1: George
    Пользователь 2: Janet

    Получаем данные радиостанций

    Есть такой интересный сервис под названием Radio Browser. Он располагается по этой ссылке и представляет собой бесплатный общедоступный каталог интернет-радио и телестанций, который создается силами сообщества по принципу Википедии. И у этого каталога есть свой API, работать с которым можно при помощи специальных библиотек. Доступны библиотеки для языков Java, Rust, Go, Python и прочих. Для Python есть библиотека pyradios. Перед использованием ее сначала надо установить:

    pip install pyradios

    Теперь получим с ее помощью данные о станции 1.FM — Deep House Radio. Делается это очень просто:

    from pyradios import RadioBrowser
    
    rb = RadioBrowser()
    results = rb.search(name="1.FM - Deep House Radio")
    
    print(results)

    Сначала импортируем из библиотеки pyradios класс RadioBrowser. Далее создаем экземпляр этого класса rb и с его помощью производим поиск необходимой станции посредством метода search, передав ему на вход название станции. И наконец, выводим результаты в консоль. Получим такой вывод:

    [{'changeuuid': 'eef536af-cb02-495c-ba90-0feadeebe30c', 'stationuuid': '962a748b-0601-11e8-ae97-52543be04c81', 'serveruuid': None, 'name': '1.FM - Deep House Radio', 'url': 'http://strm112.1.fm/deephouse_mobile_mp3', 'url_resolved': 'http://strm112.1.fm/deephouse_mobile_mp3', 'homepage': 'http://www.1.fm/', 'favicon': '', 'tags': 'deep house,techno', 'country': 'Switzerland', 'countrycode': 'CH', 'iso_3166_2': '', 'state': '', 'language': 'english', 'languagecodes': 'en', 'votes': 19188, 'lastchangetime': '2026-01-15 03:14:59', 'lastchangetime_iso8601': '2026-01-15T03:14:59Z', 'codec': 'MP3', 'bitrate': 256, 'hls': 0, 'lastcheckok': 1, 'lastchecktime': '2026-08-26 16:46:58', 'lastchecktime_iso8601': '2026-08-26T16:46:58Z', 'lastcheckoktime': '2026-08-26 16:46:58', 'lastcheckoktime_iso8601': '2026-08-26T16:46:58Z', 'lastlocalchecktime': '2026-08-26 16:46:58', 'lastlocalchecktime_iso8601': '2026-08-26T16:46:58Z', 'clicktimestamp': '2026-08-30 01:02:33', 'clicktimestamp_iso8601': '2026-08-30T01:02:33Z', 'clickcount': 59, 'clicktrend': 59, 'ssl_error': 0, 'geo_lat': None, 'geo_long': None, 'geo_distance': None, 'has_extended_info': False}]

    Данные станции получены. Как из этих данных вытянуть, например, URL станции? Очень просто! Так как данные представлены в виде словаря, то обращаемся к первому элементу и далее берем URL потока по ключу url:

    if not results:
        print("Радиостанция не найдена")
    else:
        stream_url = results[0]["url"]
        print(f"URL потока: {stream_url}")

    Здесь мы еще добавили проверку результатов через условную конструкцию if – else. В консоли получим:

    URL потока: http://strm112.1.fm/deephouse_mobile_mp3

    Зная  URL потока станции, можно попытаться проиграть ее. Для этого нам понадобится модуль subprocess, который позволяет запускать внешние программы и управлять ими прямо из кода. Еще понадобится плеер MPV. Скачать его можно отсюда. Именно в нем и будет проигрываться станция, но самого плеера не будет видно — будет запущен только его процесс в фоне. После импорта модуля в else надо добавить только одну строчку:

    subprocess.run(["mpv", stream_url])

    Весь код будет выглядеть так:

    import subprocess
    from pyradios import RadioBrowser
    
    rb = RadioBrowser()
    results = rb.search(name="1.FM - Deep House Radio")
    
    if not results:
        print("Радиостанция не найдена")
    else:
        stream_url = results[0]["url"]
        print(f"URL потока: {stream_url}")
    
        subprocess.run(["mpv", stream_url])

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

    Разбор

    Поделиться

    Скопировано
    0 комментариев
    Комментарии