0Pricing
AI Agents · Lekcja

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 bytes

Parsowanie 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 returns

Limit 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 None

Rejestrowanie 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 response

Obsł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_items

Strumieniowanie 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_code przed 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ć ConnectionError w przypadku awarii sieci i Timeout w 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

  1. Podstawy REST API dla twórców agentów
  2. Uwierzytelnianie: klucze API i OAuth
  3. Obsługa odpowiedzi i błędów API
  4. Ograniczanie liczby żądań i logika ponawiania
← Powrót do AI Agents