Обработка ответов API и ошибок
Разбор ответов JSON, кодов ошибок и шаблонов обработки исключений.
«Обработка ответов API и ошибок» — бесплатный урок AI Agents на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Agents, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Agents содержит 4 уроков всего.
Объект ответа
Каждый вызов requests возвращает объект ответа. Он содержит всё, что сервер отправил в ответ: код состояния, заголовки и тело. Перед обработкой тела всегда проверяйте код состояния: ответ со статусом 500 всё ещё содержит тело, но в нём не будет нужных Вам данных.
import requests
response = requests.get('https://api.example.com/data')
# Key attributes of the response
print(response.status_code) # e.g. 200
print(response.headers) # dict of response headers
print(response.headers.get('Content-Type')) # 'application/json'
print(response.text) # raw response body as string
print(response.content) # raw bytesРазбор JSON с помощью response.json()
Вызовите response.json(), чтобы автоматически разобрать тело ответа как JSON в словарь или список Python. Это эквивалентно json.loads(response.text), но дополнительно проверяет соответствие типа содержимого.
Вызывайте .json(), только если уверены, что ответ действительно содержит JSON: сначала проверьте заголовок Content-Type.
import requests
response = requests.get(
'https://api.example.com/users/42',
headers={'Authorization': 'Bearer YOUR_KEY'}
)
# Parse JSON body
user = response.json()
# Access fields safely with .get()
name = user.get('name', 'Unknown')
email = user.get('email', '')
roles = user.get('roles', [])
print(f'User: {name} ({email})')
print(f'Roles: {roles}')Проверка кода состояния перед разбором
Никогда не вызывайте response.json(), предварительно не убедившись, что запрос выполнен успешно. Ответы с ошибками (4xx/5xx) часто содержат подробности ошибки в формате JSON — это полезно для отладки, но это не те данные, которые Вам нужны. Сначала всегда проверяйте код состояния.
import requests
response = requests.post(
'https://api.example.com/tasks',
json={'title': 'Write report'},
headers={'Authorization': 'Bearer YOUR_KEY'}
)
if response.status_code == 201:
task = response.json()
print('Task created, ID:', task['id'])
elif response.status_code == 400:
error = response.json()
print('Validation error:', error.get('message'))
elif response.status_code == 401:
print('Auth failed — check your token')
else:
print(f'Unexpected status {response.status_code}: {response.text[:200]}')raise_for_status() — автоматическое создание исключений при ошибках
response.raise_for_status() автоматически вызывает исключение HTTPError, если код состояния равен 4xx или 5xx. Это удобный способ преобразовать некорректные ответы HTTP в исключения Python и использовать конструкцию try/except вместо длинных цепочек if/elif.
import requests
from requests.exceptions import HTTPError
try:
response = requests.get(
'https://api.example.com/users/9999',
headers={'Authorization': 'Bearer YOUR_KEY'}
)
response.raise_for_status() # raises if status >= 400
user = response.json()
print('Found user:', user['name'])
except HTTPError as e:
print(f'HTTP error: {e.response.status_code}')
print('Details:', e.response.text[:300])Обработка ошибки разбора JSON
Иногда API возвращает ответ не в формате JSON, хотя Вы его ожидаете: страницу ошибки сервера в формате HTML, пустое тело или двоичный файл. Вызов response.json() для таких ответов вызывает исключение json.JSONDecodeError. Всегда перехватывайте это исключение, чтобы агент не завершился незаметно.
import requests
import json
response = requests.get(
'https://api.example.com/report',
headers={'Authorization': 'Bearer YOUR_KEY'}
)
try:
data = response.json()
except json.JSONDecodeError as e:
print(f'Response is not valid JSON: {e}')
print('Content-Type:', response.headers.get('Content-Type'))
print('First 200 chars:', response.text[:200])
# Decide: is this an HTML error page? A CSV file?
data = None
if data is None:
print('Falling back to text processing')ConnectionError — проблемы с сетью
ConnectionError возникает, когда агент вообще не может связаться с сервером: например, при сбое разрешения DNS, отключённом сервере или блокировке запроса брандмауэром. Это сбой на уровне сети, произошедший ещё до установления соединения HTTP.
В отличие от ошибки 5xx, это не ответ сервера: соединение вообще не было установлено.
import requests
from requests.exceptions import ConnectionError
try:
response = requests.get('https://api.example.com/data')
data = response.json()
except ConnectionError as e:
print('Cannot reach server. Possible causes:')
print('- DNS failure (bad hostname)')
print('- Server is down')
print('- No internet connection')
print('- Firewall blocking the port')
print(f'Error detail: {e}')
# Consider: queue the request for retry when connectivity returnsВремя ожидания — защита от зависания агентов
По умолчанию requests бесконечно ждёт ответа. Медленный сервер или сервер, переставший отвечать, может навсегда заблокировать агента. Всегда задавайте время ожидания: кортеж (connect_timeout, read_timeout) в секундах. Если сервер не ответит вовремя, будет вызвано исключение Timeout.
import requests
from requests.exceptions import Timeout
try:
response = requests.get(
'https://api.example.com/slow-endpoint',
headers={'Authorization': 'Bearer YOUR_KEY'},
timeout=(5, 30) # 5s to connect, 30s to read
)
data = response.json()
except Timeout:
print('Request timed out after 30 seconds')
print('Options: retry, use cached result, or alert operator')Комплексная обработка исключений
В рабочих агентах перехватывайте все исключения requests в единой иерархии. requests.exceptions.RequestException — базовый класс для всех ошибок библиотеки запросов; его перехват обеспечивает защиту от непредвиденных проблем с сетью.
import requests
import json
from requests.exceptions import (
ConnectionError, Timeout, HTTPError, RequestException
)
def safe_api_call(url, headers):
try:
r = requests.get(url, headers=headers, timeout=(5, 30))
r.raise_for_status()
return r.json()
except Timeout:
print('ERROR: Request timed out')
except ConnectionError:
print('ERROR: Cannot reach server')
except HTTPError as e:
print(f'ERROR: HTTP {e.response.status_code}')
try:
print('API error:', e.response.json().get('message'))
except json.JSONDecodeError:
print('Non-JSON error body')
except RequestException as e:
print(f'ERROR: Unexpected request error: {e}')
return NoneВедение журналов ответов для отладки
Когда агент работает неправильно, Вам нужен достаточный контекст для диагностики. Записывайте в журнал метод запроса, URL, код состояния и важные сведения об ответе, но никогда не записывайте ключи API. В рабочих агентах используйте встроенный модуль Python logging, а не инструкции print.
import logging
import requests
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('agent.api')
def logged_request(method, url, **kwargs):
logger.info(f'-> {method.upper()} {url}')
response = requests.request(method, url, **kwargs)
logger.info(
f'<- {response.status_code} '
f'({len(response.content)} bytes) '
f'{response.elapsed.total_seconds():.2f}s'
)
if response.status_code >= 400:
logger.error(f'Error body: {response.text[:500]}')
return responseОбработка постраничных ответов
Многие API возвращают данные по страницам. Агент должен переходить по ссылкам пагинации, чтобы получить все результаты. Ищите в ответе URL next или поле page/cursor и повторяйте запросы, пока страницы не закончатся.
import requests
def get_all_items(base_url, headers):
all_items = []
url = f'{base_url}/items?page=1&limit=100'
while url:
response = requests.get(url, headers=headers)
response.raise_for_status()
data = response.json()
all_items.extend(data.get('items', []))
# Follow 'next' link if present
url = data.get('next_page_url') # None stops the loop
print(f'Fetched {len(all_items)} items so far...')
print(f'Total: {len(all_items)} items')
return all_itemsПотоковая передача больших ответов
Для больших ответов (файлов и длинных ответов ИИ) используйте stream=True, чтобы не загружать весь ответ в память сразу. Считывайте ответ фрагментами. Это особенно важно, когда агент обрабатывает большие наборы данных или передаёт текст, созданный ИИ, в потоковом режиме.
import requests
response = requests.get(
'https://api.example.com/large-report',
headers={'Authorization': 'Bearer YOUR_KEY'},
stream=True
)
response.raise_for_status()
# Write streamed content to file
with open('report.json', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
print('Download complete')
# For streaming JSON lines (NDJSON):
for line in response.iter_lines():
if line:
import json
record = json.loads(line)
print(record)Быстрая проверка: raise_for_status
Проверьте, насколько хорошо Вы понимаете обработку ошибок в ответах.
Итоги обработки ответов
Надёжная обработка ответов отличает хрупкого агента от надёжного:
- Всегда проверяйте
status_codeперед разбором тела - Используйте
response.json()для разбора и перехватывайтеJSONDecodeError, если тело может быть не в формате JSON - Используйте
raise_for_status(), чтобы преобразовывать ошибки HTTP в исключения - Перехватывайте
ConnectionErrorпри сбоях сети иTimeoutпри медленной работе серверов - Всегда задавайте кортеж
timeout=(connect, read)для каждого запроса - Записывайте запросы и ответы в журнал (без ключей), чтобы упростить отладку
Часто задаваемые вопросы
Урок «Обработка ответов API и ошибок» бесплатный?
Да — полный текст урока «Обработка ответов API и ошибок» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Agents, подпишись на CoddyKit PRO. Курс AI Agents содержит 4 уроков всего.
Чему я научусь в уроке «Обработка ответов API и ошибок»?
Разбор ответов JSON, кодов ошибок и шаблонов обработки исключений. Ты практикуешь AI Agents с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Agents?
Предыдущий опыт не требуется. AI Agents на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Обработка ответов API и ошибок»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Agents?
Да. Каждый урок AI Agents включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы REST API для разработчиков агентов
- Аутентификация: ключи API и OAuth
- Обработка ответов API и ошибок
- Ограничение частоты запросов и логика повторных попыток