Python 강좌 / HTTP와 API 기초: 요청·응답·JSON·오류 처리
HTTP API는 요청을 보내 상태 코드와 응답 데이터를 받아 사용하는 인터페이스입니다. Python에서는 요청 성공 여부, 대기 시간, 응답 크기와 JSON 구조를 각각 확인해야 합니다.
HTTP·URL·JSON의 역할
HTTP는 요청·응답 통신 규약이고 URL은 접속 대상을 지정합니다. JSON은 응답 본문의 한 형식이며 HTTP 요청이 성공해도 데이터가 기대한 구조인지 별도 검증해야 합니다. 실제 외부 서비스는 HTTPS, 인증 방식, 요청 한도와 이용 조건을 확인합니다.
관련 동작과 지원 조건은 HTTP와 API 기초: 요청·응답·JSON·오류 처리 관련 공식 문서에서 확인할 수 있습니다.
실습은 외부 API의 변경에 의존하지 않도록 로컬 테스트 서버를 사용합니다. 운영 서버를 만드는 방법이 아니라 클라이언트가 응답을 읽는 흐름을 확인하기 위한 서버입니다.
테스트 응답과 서버 준비
expenses.json 파일의 전체 내용입니다.
[{"id":"e1","name":"coffee","amount":3500},{"id":"e2","name":"lunch","amount":8000}]
첫 번째 터미널에서 파일이 있는 폴더로 이동해 아래 명령을 실행합니다. 127.0.0.1에만 바인딩하여 같은 PC에서 접근합니다. 포트가 사용 중이면 다른 포트로 바꾸고 요청 URL도 맞춥니다.
python -m http.server 8000 --bind 127.0.0.1
클라이언트 전체 예제
fetch_expenses.py 파일의 전체 내용입니다.
import json
import sys
from urllib.request import urlopen
from urllib.error import HTTPError, URLError
url = sys.argv[1]
try:
with urlopen(url, timeout=5) as response:
if response.status != 200:
raise ValueError("unexpected status")
raw = response.read(1_000_001)
if len(raw) > 1_000_000:
raise ValueError("response too large")
data = json.loads(raw.decode("utf-8"))
except (HTTPError, URLError, TimeoutError, UnicodeError, ValueError) as error:
raise SystemExit(f"request failed: {type(error).__name__}")
if not isinstance(data, list):
raise SystemExit("expected a list")
total = 0
for row in data:
if not isinstance(row, dict) or type(row.get("amount")) is not int or row["amount"] < 0:
raise SystemExit("invalid record")
total += row["amount"]
print("records:", len(data))
print("total:", total)
같은 가상환경을 선택한 두 번째 터미널에서 실행합니다.
python fetch_expenses.py http://127.0.0.1:8000/expenses.json
정상 응답은 records: 2와 total: 11500을 출력합니다. 테스트를 마치면 서버 터미널에서 Ctrl+C로 종료합니다.
네트워크 실패와 데이터 실패 구분하기
존재하지 않는 경로는 HTTPError, 서버 연결 실패는 URLError 등으로 나타날 수 있습니다. timeout은 개별 네트워크 대기의 제한이며 전체 작업의 절대 마감 시간을 보장하는 것과 다릅니다. 응답이 크거나 JSON이 깨져도 이 예제는 오류로 중단합니다.
재시도를 넣을 때는 횟수와 간격을 제한하고 요청의 부작용 여부를 확인합니다. 결제 같은 쓰기 요청을 무조건 반복하면 중복 작업이 생길 수 있습니다. 인증 토큰은 코드·URL·로그에 직접 남기지 않고 서비스 정책에 맞춰 관리합니다.
- expenses.json 이름을 요청 URL에서 잘못 적어 HTTP 실패를 확인합니다.
- amount를 문자열로 바꾸어 구조 검증에서 거부되는지 확인합니다.
- 서버를 종료한 뒤 연결 실패가 정상 응답과 구분되는지 확인합니다.




