Obsługa odpowiedzi i błędów API
Parsowanie odpowiedzi JSON, kody błędów i wzorce obsługi wyjątków.
Obsługa odpowiedzi i błędów API to bezpłatna lekcja AI Agents na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Agents, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Agents zawiera 4 lekcji w sumie.
Obiekt Response
Każde wywołanie requests zwraca obiekt Response. Zawiera on wszystko, co zwrócił serwer: kod statusu, nagłówki i treść odpowiedzi. Przed przetworzeniem treści należy zawsze sprawdzić kod statusu — odpowiedź ze statusem 500 nadal zawiera treść, ale nie będzie ona zawierać potrzebnych danych.
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 bytesParsowanie JSON za pomocą response.json()
Wywołanie response.json() automatycznie parsuje treść odpowiedzi jako JSON do słownika lub listy w Pythonie. Jest to odpowiednik json.loads(response.text), ale dodatkowo sprawdza, czy wartość Content-Type jest odpowiednia.
Metodę .json() należy wywoływać tylko wtedy, gdy wiadomo, że odpowiedź rzeczywiście ma format JSON — najpierw należy sprawdzić nagłówek 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}')Sprawdzanie status_code przed parsowaniem
Nigdy nie należy wywoływać response.json() bez uprzedniego potwierdzenia, że żądanie zakończyło się powodzeniem. Odpowiedzi błędów (4xx/5xx) często zawierają szczegóły błędu w formacie JSON — są one przydatne podczas debugowania, ale nie stanowią potrzebnych danych. Zawsze należy najpierw sprawdzić status_code.
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() — automatyczne zgłaszanie błędów
response.raise_for_status() automatycznie zgłasza wyjątek HTTPError, jeśli kod statusu ma wartość 4xx lub 5xx. To przejrzysty sposób przekształcania nieprawidłowych odpowiedzi HTTP w wyjątki Pythona, dzięki czemu można używać try/except zamiast długich łańcuchów 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])Obsługa JSONDecodeError
Czasami interfejs API zwraca odpowiedź inną niż JSON, mimo że oczekiwano formatu JSON — na przykład stronę błędu serwera w HTML, pustą treść lub plik binarny. Wywołanie response.json() dla takich danych powoduje zgłoszenie wyjątku json.JSONDecodeError. Należy go zawsze przechwytywać, aby uniknąć cichych awarii agenta.
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 — problemy z siecią
Wyjątek ConnectionError występuje, gdy agent w ogóle nie może połączyć się z serwerem — na przykład z powodu nieudanego rozpoznawania DNS, wyłączenia serwera lub zablokowania żądania przez zaporę. To awaria na poziomie sieci, zanim w ogóle dojdzie do komunikacji HTTP.
W przeciwieństwie do błędu 5xx nie jest to odpowiedź serwera — połączenie w ogóle nie zostało nawiązane.
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 returnsLimit czasu — zapobieganie zawieszaniu agentów
Domyślnie biblioteka requests czeka bez końca na odpowiedź. Powolny lub zawieszony serwer może więc zablokować agenta na czas nieokreślony. Należy zawsze ustawiać limit czasu: krotkę (connect_timeout, read_timeout) wyrażoną w sekundach. Jeśli serwer nie odpowie na czas, zgłaszany jest wyjątek 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')Kompleksowa obsługa wyjątków
W agentach produkcyjnych należy spójnie przechwytywać wszystkie wyjątki biblioteki requests. requests.exceptions.RequestException to klasa bazowa wszystkich błędów biblioteki requests — jej przechwycenie zapewnia zabezpieczenie na wypadek nieoczekiwanych problemów z siecią.
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 NoneRejestrowanie odpowiedzi na potrzeby debugowania
Gdy agent działa nieprawidłowo, do zdiagnozowania problemu potrzebny jest wystarczający kontekst. Należy rejestrować metodę żądania, adres URL, kod statusu i istotne szczegóły odpowiedzi — ale nigdy nie należy rejestrować kluczy API. W agentach produkcyjnych należy używać wbudowanego modułu logging języka Python zamiast instrukcji 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 responseObsługa odpowiedzi paginowanych
Wiele interfejsów API zwraca dane w postaci stron. Agent musi korzystać z odnośników do kolejnych stron, aby pobrać wszystkie wyniki. Należy szukać adresu URL next w odpowiedzi albo pola page/cursor i wykonywać kolejne iteracje, dopóki nie będzie już następnych stron.
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_itemsStrumieniowanie dużych odpowiedzi
W przypadku dużych odpowiedzi (plików, długich wyników AI) należy użyć stream=True, aby uniknąć jednoczesnego wczytywania całej odpowiedzi do pamięci. Odpowiedź należy odczytywać partiami. Jest to niezbędne, gdy agent przetwarza duże zbiory danych lub strumieniuje tekst wygenerowany przez AI.
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)Szybkie sprawdzenie: raise_for_status
Sprawdzenie zrozumienia obsługi błędów odpowiedzi.
Podsumowanie obsługi odpowiedzi
Solidna obsługa odpowiedzi odróżnia kruchego agenta od niezawodnego:
- Zawsze należy sprawdzać
status_codeprzed parsowaniem treści - Należy używać
response.json()do parsowania i przechwytywaćJSONDecodeError, jeśli treść może nie być zapisana w formacie JSON - Należy używać
raise_for_status(), aby przekształcać błędy HTTP w wyjątki - Należy przechwytywać
ConnectionErrorw przypadku awarii sieci iTimeoutw przypadku powolnych serwerów - W każdym żądaniu należy zawsze ustawiać krotkę
timeout=(connect, read) - Należy rejestrować żądania i odpowiedzi (bez kluczy), aby ułatwić diagnozowanie problemów
Często zadawane pytania
Czy lekcja „Obsługa odpowiedzi i błędów API” jest bezpłatna?
Tak — pełny tekst „Obsługa odpowiedzi i błędów API” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Agents, przejdź na CoddyKit PRO. Kurs AI Agents zawiera 4 lekcji w sumie.
Co nauczysz się w „Obsługa odpowiedzi i błędów API”?
Parsowanie odpowiedzi JSON, kody błędów i wzorce obsługi wyjątków. Ćwiczysz AI Agents z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć AI Agents?
Nie wymagamy żadnego doświadczenia. AI Agents w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Obsługa odpowiedzi i błędów API”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji AI Agents?
Tak. Każda lekcja AI Agents zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Podstawy REST API dla twórców agentów
- Uwierzytelnianie: klucze API i OAuth
- Obsługa odpowiedzi i błędów API
- Ograniczanie liczby żądań i logika ponawiania