API 응답 및 오류 처리
JSON 응답 파싱, 오류 코드, 예외 처리 패턴을 알아봅니다.
API 응답 및 오류 처리은(는) CoddyKit의 무료 AI Agents 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 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 bytesresponse.json()으로 JSON 파싱하기
response.json()을 호출하면 응답 본문을 JSON으로 자동 파싱하여 Python 딕셔너리나 목록으로 변환합니다. 이는 json.loads(response.text)와 같지만 Content-Type이 적절한지도 확인합니다.
응답이 실제로 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 오류 세부 정보를 반환하는 경우가 많지만, 필요한 데이터는 아닙니다. 항상 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() — 자동 오류 발생
상태 코드가 4xx 또는 5xx이면 response.raise_for_status()가 자동으로 HTTPError 예외를 발생시킵니다. 이는 잘못된 HTTP 응답을 Python 예외로 바꾸는 깔끔한 방법이므로, 긴 조건문 연쇄 대신 try/except를 사용할 수 있습니다.
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 디코딩 오류 처리
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은 모든 requests 오류의 기본 클래스이므로, 이를 처리하면 예상하지 못한 네트워크 문제에 대한 안전망을 마련할 수 있습니다.
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 모듈을 사용하세요.
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가 데이터를 여러 페이지로 나누어 반환합니다. 모든 결과를 가져오려면 에이전트가 페이지 매김 링크를 따라가야 합니다. 응답에서 next URL이나 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대용량 응답 스트리밍하기
대용량 응답(파일, 긴 AI 출력)을 처리할 때는 stream=True를 사용하여 전체 응답을 한 번에 메모리에 올리지 않도록 하세요. 응답을 여러 조각으로 나누어 읽으세요. 에이전트가 대규모 데이터 세트를 처리하거나 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)빠른 확인: raise_for_status
응답 오류 처리에 대한 이해도를 확인해 보세요.
응답 처리 복습
견고한 응답 처리는 취약한 에이전트와 신뢰할 수 있는 에이전트를 가르는 요소입니다.
- 본문을 파싱하기 전에 항상
status_code를 확인하세요 response.json()으로 파싱하고, 본문이 JSON이 아닐 수 있다면JSONDecodeError를 처리하세요raise_for_status()를 사용하여 HTTP 오류를 예외로 바꾸세요- 네트워크 실패에는
ConnectionError를, 느린 서버에는Timeout을 처리하세요 - 모든 요청에 항상
timeout=(connect, read)튜플을 설정하세요 - 디버깅할 수 있도록 키를 제외한 요청과 응답을 기록하세요
자주 묻는 질문
“API 응답 및 오류 처리” 강의는 무료인가요?
네 — “API 응답 및 오류 처리” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Agents 강의 전체를 잠금 해제할 수 있습니다. AI Agents 강의에는 총 4개의 강의가 포함되어 있습니다.
“API 응답 및 오류 처리”에서 뭘 배우나요?
JSON 응답 파싱, 오류 코드, 예외 처리 패턴을 알아봅니다. 브라우저에서 직접 실행하는 실습 코드로 AI Agents을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Agents을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Agents은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“API 응답 및 오류 처리” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Agents 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Agents 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 에이전트 개발자를 위한 REST API 기초
- 인증: API 키와 OAuth
- API 응답 및 오류 처리
- 요청 제한 및 재시도 로직