Работа с API в Python: полное руководство по библиотеке requests

Узнайте, как работать с API в Python с помощью библиотеки requests. В статье практические примеры GET и POST запросов, обработка ошибок, работа с заголовками и аутентификацией, загрузка файлов. Полное руководство от основ до продвинутых техник для разработчиков.

РазработкаPython

6 мин

Почему requests?

Python включает встроенный модуль urllib для работы с HTTP, но его синтаксис громоздкий и неинтуитивный. Библиотека requests решает эту проблему, предоставляя элегантный и понятный интерфейс. Недаром её слоган — "HTTP for Humans".

Установка

Установить requests проще простого:

pip install requests

Основы работы: GET-запросы

Начнём с самого распространённого типа запросов — GET. Представим, что нам нужно получить данные о пользователе GitHub:

import requests

response = requests.get('https://api.github.com/users/octocat')

# Проверяем статус ответа
print(response.status_code)  # 200

# Получаем JSON
data = response.json()
print(data['name'])  # The Octocat
print(data['public_repos'])  # Количество публичных репозиториев

Объект response содержит всю информацию об ответе сервера: статус-код, заголовки, тело ответа и многое другое.

Параметры запроса

Часто API требуют передачи параметров в URL. Библиотека requests позволяет делать это элегантно:

# Поиск репозиториев на GitHub
params = {
    'q': 'python requests',
    'sort': 'stars',
    'order': 'desc'
}

response = requests.get('https://api.github.com/search/repositories', params=params)
repos = response.json()

for repo in repos['items'][:5]:
    print(f"{repo['name']}: {repo['stargazers_count']} звёзд")

Библиотека автоматически формирует правильный URL с параметрами, экранируя специальные символы.

POST-запросы и отправка данных

POST-запросы используются для создания ресурсов или отправки форм. Рассмотрим пример с отправкой JSON:

# Создание нового ресурса
data = {
    'title': 'Изучаю requests',
    'body': 'Это очень удобная библиотека!',
    'userId': 1
}

response = requests.post('https://jsonplaceholder.typicode.com/posts', json=data)

if response.status_code == 201:
    print('Ресурс создан!')
    print(response.json())

Обратите внимание на параметр json — requests автоматически сериализует словарь в JSON и устанавливает правильный заголовок Content-Type.

Работа с заголовками

Многие API требуют аутентификации через заголовки. Вот как это делается:

headers = {
    'Authorization': 'Bearer YOUR_TOKEN_HERE',
    'User-Agent': 'MyApp/1.0'
}

response = requests.get('https://api.example.com/data', headers=headers)

Некоторые API используют API-ключи:

headers = {'X-API-Key': 'your_api_key'}
response = requests.get('https://api.example.com/protected', headers=headers)

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

Профессиональная работа с API невозможна без правильной обработки ошибок:

try:
    response = requests.get('https://api.example.com/data', timeout=5)
    response.raise_for_status()  # Выбросит исключение для кодов 4xx и 5xx
    
    data = response.json()
    
except requests.exceptions.HTTPError as http_err:
    print(f'HTTP ошибка: {http_err}')
except requests.exceptions.ConnectionError:
    print('Ошибка подключения')
except requests.exceptions.Timeout:
    print('Превышено время ожидания')
except requests.exceptions.RequestException as err:
    print(f'Произошла ошибка: {err}')

Метод raise_for_status() автоматически выбрасывает исключение, если сервер вернул код ошибки.

Сессии для множественных запросов

Если вам нужно сделать несколько запросов к одному API, используйте сессии. Они сохраняют cookies и соединение, что значительно ускоряет работу:

session = requests.Session()
session.headers.update({'Authorization': 'Bearer TOKEN'})

# Все запросы внутри сессии будут использовать общие заголовки
response1 = session.get('https://api.example.com/users')
response2 = session.get('https://api.example.com/posts')
response3 = session.post('https://api.example.com/comments', json={'text': 'Hello'})

session.close()

Ещё лучше использовать контекстный менеджер:

with requests.Session() as session:
    session.headers.update({'Authorization': 'Bearer TOKEN'})
    response = session.get('https://api.example.com/data')

Работа с файлами

Загрузка файлов через API тоже не составляет труда:

# Загрузка файла
files = {'file': open('document.pdf', 'rb')}
response = requests.post('https://api.example.com/upload', files=files)

# Скачивание файла
response = requests.get('https://example.com/image.jpg', stream=True)
with open('image.jpg', 'wb') as file:
    for chunk in response.iter_content(chunk_size=8192):
        file.write(chunk)

Параметр stream=True позволяет загружать большие файлы порциями, не загружая их полностью в память.

Практический пример: работа с погодным API

Давайте создадим полноценное приложение для получения погоды:

import requests

def get_weather(city, api_key):
    """Получает текущую погоду для указанного города"""
    base_url = "http://api.openweathermap.org/data/2.5/weather"
    
    params = {
        'q': city,
        'appid': api_key,
        'units': 'metric',
        'lang': 'ru'
    }
    
    try:
        response = requests.get(base_url, params=params, timeout=10)
        response.raise_for_status()
        
        data = response.json()
        
        weather_info = {
            'город': data['name'],
            'температура': data['main']['temp'],
            'ощущается': data['main']['feels_like'],
            'описание': data['weather'][0]['description'],
            'влажность': data['main']['humidity'],
            'ветер': data['wind']['speed']
        }
        
        return weather_info
        
    except requests.exceptions.RequestException as e:
        print(f"Ошибка при получении данных: {e}")
        return None

# Использование
weather = get_weather('Москва', 'YOUR_API_KEY')
if weather:
    print(f"Погода в городе {weather['город']}:")
    print(f"Температура: {weather['температура']}°C")
    print(f"Ощущается как: {weather['ощущается']}°C")
    print(f"Описание: {weather['описание']}")

Расширенные возможности

Retry-механизм с помощью адаптеров:

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

session = requests.Session()
retry = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)

response = session.get('https://api.example.com/data')

Работа с аутентификацией:

# Basic Auth
response = requests.get('https://api.example.com/data', 
                       auth=('username', 'password'))

# OAuth 2.0 обычно через заголовки
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get('https://api.example.com/data', headers=headers)

Заключение

Библиотека requests превращает работу с API в Python в удовольствие. Простой и интуитивный синтаксис, мощные возможности и отличная документация делают её стандартом де-факто для HTTP-запросов в Python. Освоив requests, вы сможете интегрировать в свои проекты тысячи различных сервисов и создавать по-настоящему мощные приложения.

Приложение Кодик предлагает структурированные курсы по Python, JavaScript, работе с API и многому другому. Интерактивные уроки, практические задания и пошаговое изучение помогут вам стать разработчиком.

Присоединяйтесь к нашему Telegram-каналу, где вы найдёте поддержку опытных разработчиков, полезные материалы и ответы на любые вопросы по программированию. Учитесь в комфортном темпе вместе с сообществом единомышленников!

Комментарии