Narwhal API는 CC BY 4.0에 따라 세계은행 WDI 연간 지표 1,489개를 색인합니다. Python으로 세계은행 데이터를 조회하려면 지표를 검색하고, ID 템플릿에 소문자 국가 코드를 넣은 다음 API 키로 관측값을 요청하세요. 응답에는 기간, 소수 문자열 값, 출처 표시, 라이선스 URL이 포함됩니다. 요금제에 따라 이력 조회 기간과 캐시되지 않은 데이터의 일일 가져오기 한도가 결정됩니다.
API 사용 방법
- 무료 키 발급과 Python 준비 회원가입에서 계정을 만들고 API 키를 발급받은 다음, Python을 실행할 셸에서
NARWHAL_API_KEY를 설정하세요. 자리표시자를 발급받은 키로 바꾸세요. HTTP 호출용requests와 DataFrame용pandas를 설치하세요. 각 요청은 Authorization 헤더에 키를 사용하며, 마지막 단계의 전체 스크립트는 환경 변수에서 키를 읽습니다.python -m pip install requests pandas export NARWHAL_API_KEY="replace-with-your-key" - 지표 검색
source=wdi로 카탈로그에서gdp per capita를 검색하세요. 각 결과의id_template과 제목을 출력한 다음 필요한 지표를 선택하세요. 카탈로그 검색은 모든 요금제에서 이용할 수 있으며 원본 출처를 호출하지 않습니다.params인수는 검색어의 공백을 처리합니다. 검색 결과는 지표를 설명하며, 국가는 다음 단계에서 만드는 시계열 ID에 넣습니다.import os import requests BASE_URL = "https://api.narwhalapi.com" headers = { "Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}" } response = requests.get( f"{BASE_URL}/v1/economics/catalogue", headers=headers, params={"q": "gdp per capita", "source": "wdi"}, timeout=10, ) response.raise_for_status() catalogue = response.json() for hit in catalogue["results"]: print(hit["id_template"], hit["title"]) - 템플릿에 국가 추가 선택한 템플릿의
{country}를 소문자 ISO 3166-1 alpha-3 코드로 바꾸세요. 인도네시아는idn을 사용합니다. 세계은행 ID의 형식은wdi:<indicator>/<iso3>이며, 지표와 국가 사이에 슬래시가 포함됩니다. 전체 ID를id쿼리 매개변수로 전달하세요. 코드 예제는 첫 번째 검색 결과를 선택하므로 사용하기 전에 출력된 제목을 확인하세요.if not catalogue["results"]: raise SystemExit("No matching indicators found.") selected = catalogue["results"][0] series_id = selected["id_template"].replace("{country}", "idn") print(series_id) - 연간 관측값 조회 해당 ID의 관측값을 요청하세요. 연간 기간은
YYYY를 사용하며, 선택 사항인start와end는 경곗값을 포함합니다. 응답 개수 제한은 최대 1,000개이며 기본값은 100입니다.next_cursor에 값이 있으면 이를cursor로 전달하여 계속 조회하세요. 개수 제한을 늘려도 요금제의 이력 조회 기간은 확장되지 않으며, 데이터가 없는 연도는 응답에 포함되지 않습니다.response = requests.get( f"{BASE_URL}/v1/economics/catalogue/series/observations", headers=headers, params={"id": series_id, "limit": 1000}, timeout=10, ) response.raise_for_status() observations = response.json()["observations"] - DataFrame 생성 관측값으로 DataFrame을 만들고
period를 정수로,value를 부동소수점 수로 변환하세요. 값은 소수 문자열로 반환됩니다. 십진 연산이 필요하면float()대신Decimal을 사용하세요. 분석할 때 응답의 단위 레이블을 함께 유지하세요. 지표의 제목은 해당 값이 무엇을 측정하는지 설명합니다. 이 변환은 빈 구간을 채우거나 데이터가 없는 연도의 관측값을 생성하지 않습니다.import pandas as pd frame = pd.DataFrame(observations, columns=["period", "value"]) frame["period"] = frame["period"].astype(int) frame["value"] = frame["value"].map(float) print(frame) - 국가별 일괄 조회와 요청 오류 처리 이 전체 스크립트를 실행하여 예제의 GDP 시계열과 인도네시아 및 캐나다의 최신값을 일괄 조회하세요. ID는 쉼표로 연결합니다. 최신값 엔드포인트는 서로 다른 ID 1~50개를 허용합니다. 반환된 시계열당 호출 1회가 한 번에 차감됩니다. 스크립트는 각 국가의 기간과 값을 출력하고, 누락된 ID를 알리며, 400, 404 또는
429 fetch_limit_reached응답이 오면 오류 메시지와 함께 중단됩니다.import os import requests import pandas as pd BASE_URL = "https://api.narwhalapi.com" HEADERS = { "Authorization": f"Bearer {os.environ['NARWHAL_API_KEY']}" } def get_json(path, params): response = requests.get( f"{BASE_URL}{path}", headers=HEADERS, params=params, timeout=10, ) try: response.raise_for_status() except requests.HTTPError: problem = response.json() code = problem.get("code", "unknown_error") if response.status_code == 429 and code == "fetch_limit_reached": retry_after = response.headers.get("Retry-After") raise SystemExit( f"Uncached fetch allowance used. Retry-After: {retry_after}" ) if response.status_code in (400, 404): raise SystemExit(f"{code}: {problem.get('detail', '')}") raise return response.json() series_id = "wdi:ny.gdp.mktp.cd/idn" rows = [] params = {"id": series_id, "limit": 1000} while True: payload = get_json( "/v1/economics/catalogue/series/observations", params ) rows.extend(payload["observations"]) cursor = payload.get("next_cursor") if not cursor: break params["cursor"] = cursor frame = pd.DataFrame(rows, columns=["period", "value"]) frame["period"] = frame["period"].astype(int) frame["value"] = frame["value"].map(float) print(frame) countries = ("idn", "can") ids = [f"wdi:ny.gdp.mktp.cd/{country}" for country in countries] batch = get_json( "/v1/economics/catalogue/latest", {"ids": ",".join(ids)}, ) for observation in batch["observations"]: country = observation["id"].rsplit("/", 1)[1] print(country, observation["period"], observation["value"]) for missing in batch["missing"]: print("Missing:", missing)
인도네시아 GDP 예제는 어떻게 해석하나요?
시계열 wdi:ny.gdp.mktp.cd/idn은 당해 연도 미국 달러 기준 인도네시아 GDP입니다. 2026년 10월 27일에 Pro 키로 limit=3을 지정하여 요청했을 때 이 관측값들이 반환되었습니다. 이 예제는 총 GDP를 사용합니다. 1인당 GDP가 필요하면 카탈로그 검색에서 얻은 템플릿을 사용하세요.
[
{"period": "1967", "value": "5667756627.92093"},
{"period": "1968", "value": "7076465299.81141"},
{"period": "1969", "value": "8337423312.88344"}
]1967년 값은 float("5667756627.92093")로 변환하여 DataFrame에서 수치 연산에 사용할 수 있습니다. 십진 표현도 필요하면 원본 문자열을 보존하세요. 응답에는 세계은행 WDI 출처 표시와 CC BY 4.0 라이선스 URL이 포함됩니다. 사용하는 데이터와 함께 출처 표시와 라이선스 정보를 유지하세요.
Free 키로는 왜 몇 년치만 반환되나요?
Free의 이력 조회 기간은 12개월이며, 연간 관측값은 최소한 최신 5개가 제공됩니다. Narwhal은 요금제 조회 기간과 이 최소 개수 중 더 많은 관측값을 제공하는 기준을 적용합니다. 따라서 연간 시계열은 대부분의 관측값이 일반 조회 기간을 벗어나더라도 여러 관측값을 유지합니다. 연간 최소 개수는 모든 요금제에 적용됩니다.
요금제별 적용 한도:
| 요금제 | 계정별 UTC 일일 비캐시 조회 횟수 | 이력 조회 기간 |
|---|---|---|
| 무료 | 10 | 최근 12개월, 연간 관측값은 최소한 최신 5개 |
| Basic | 100 | 최근 5년, 연간 관측값은 최소한 최신 5개 |
| Pro | 1,000 | 전체 이력 |
허용된 조회 기간보다 완전히 앞선 범위를 요청하면 403 plan_upgrade_required를 반환합니다. 연간 시계열에서는 최소 개수를 반영할 수 있도록 시계열을 불러온 후 해당 범위를 확인합니다. 요금제 상세 정보에서 분석에 필요한 이력 조회 기간을 선택하세요.
429 fetch_limit_reached 오류는 무슨 뜻인가요?
계정의 일일 한도를 모두 사용했으며, 요청을 처리하려면 캐시되지 않은 데이터를 가져와야 한다는 뜻입니다. 재시도하기 전에 Retry-After를 확인하세요. 한도는 00:00 UTC에 초기화됩니다. 한도에 도달한 후에도 캐시된 시계열은 응답합니다. 세계은행 데이터의 캐시 유지 기간은 24시간~7일이므로, 다시 요청한다고 해서 반드시 원본 데이터를 가져오는 것은 아닙니다.
400 invalid_series_id가 발생하면 지표, 슬래시, 소문자 국가 코드를 확인하세요. 400 invalid_query는 쿼리가 유효하지 않다는 뜻입니다. 404 not_found는 색인에 해당 지표가 없다는 뜻일 수 있으며, Narwhal은 이 결과를 24시간 동안 기억합니다. 요청을 반복하기 전에 카탈로그 결과와 ID를 대조하세요.
오래된 캐시 응답과 400, 404, 503 응답은 사용량에서 차감되지 않습니다. 원본 출처를 이용할 수 없고 캐시된 사본도 없으면 Narwhal은 Retry-After와 함께 503 upstream_busy를 반환합니다. 재시도 처리는 캐싱과 429 처리를 확인하세요.
에 게시되었습니다.
다음 단계
무료 키를 만들고 직접 작성한 코드에서 API를 호출하세요. 무료 API 키 받기
