Python에서 실시간 금 시세를 가져오려면 requests로 api.goldprice.dev/v1/spot/XAU-USD-SPOT에 GET 요청을 보내고 X-API-Key 헤더에 API 키를 넣으세요. 호출에 cachetools.TTLCache를 적용해 60초간 캐시하고 가격 계산에는 Decimal을 사용하세요. 무료 플랜은 월 5,000회를 제공하며 신용카드가 필요하지 않습니다. 2026년 시월에 Python 3.15 + requests 2.34에서 테스트했습니다.
goldprice.dev API 키 발급받기
goldprice.dev/onboarding에서 무료 계정을 만드세요. 이메일 인증 후 대시보드에 ga_live_로 시작하는 키가 표시됩니다. 환경 변수로 설정하세요.
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_here무료 플랜은 월 5,000회 호출과 31개 통화의 금 현물 시세를 제공합니다. 신용카드는 필요하지 않습니다.
의존성 설치하기
HTTP 호출용 requests, 프로세스 내부 TTL 캐시용 cachetools, 429 재시도용 tenacity, 이렇게 세 패키지가 필요합니다. pip 또는 uv로 설치하세요.
# pippip install requests cachetools tenacity# or uv (recommended)uv add requests cachetools tenacitygoldprice 클라이언트 작성하기
아래 코드를 goldprice.py로 저장하세요. spot() 함수는 심볼별로 60초간 캐시하고, 429 응답에는 지수 백오프로 최대 3번 재시도합니다. 가격은 Decimal로 반환해 이후 계산에서 부동소수점 오차가 누적되지 않게 합니다.
# python: goldprice.py# curl-equivalent: https://api.goldprice.dev/v1/spot/XAU-USD-SPOTimport osfrom decimal import Decimalfrom typing import TypedDictimport requestsfrom cachetools import TTLCache, cachedfrom tenacity import ( retry, retry_if_exception_type, stop_after_attempt, wait_exponential,)API_BASE = "https://api.goldprice.dev"API_KEY = os.environ["GOLDPRICE_API_KEY"]TIMEOUT = 5 # secondsclass SpotResponse(TypedDict): symbol: str quote_currency: str price: Decimal bid: Decimal | None # only on plans that include bid and ask ask: Decimal | None is_stale: bool computed_at: strclass RateLimited(Exception): """Raised on HTTP 429 so tenacity retries with backoff."""@cached(cache=TTLCache(maxsize=128, ttl=60))@retry( retry=retry_if_exception_type(RateLimited), wait=wait_exponential(multiplier=1, min=2, max=30), stop=stop_after_attempt(3), reraise=True,)def spot(symbol: str = "XAU-USD-SPOT") -> SpotResponse: """Fetch live spot price. Cached 60s per symbol, retries 3x on 429.""" resp = requests.get( f"{API_BASE}/v1/spot/{symbol}", headers={"X-API-Key": API_KEY}, timeout=TIMEOUT, ) if resp.status_code == 429: raise RateLimited(resp.text) resp.raise_for_status() data = resp.json() return { "symbol": data["symbol"], "quote_currency": data["quote_currency"], "price": Decimal(data["price"]), "bid": Decimal(data["bid"]) if data.get("bid") else None, "ask": Decimal(data["ask"]) if data.get("ask") else None, "is_stale": data["is_stale"], "computed_at": data["computed_at"], }if __name__ == "__main__": r = spot("XAU-USD-SPOT") print(f"{r['symbol']}-{r['quote_currency']}: {r['price']} (computed {r['computed_at']})")실행하기
GOLDPRICE_API_KEY를 설정한 셸에서 파일을 실행하세요. 첫 호출은 API에 요청하고, 60초 이내의 호출은 캐시된 값을 즉시 반환합니다. 캐시는 프로세스 내부에만 있으므로 새 프로세스로 실행할 때는 다시 요청합니다. 프로세스 간 캐시가 필요하면 Redis에 저장하세요.
python goldprice.py# XAU-USD: 4012.75 (computed 2026-10-23T07:00:18.221118+00:00)통화 또는 금속 바꾸기
심볼 형식은 METAL-CURRENCY-SPOT입니다. 지원하는 31개 현물 통화의 심볼을 spot()에 전달하세요. TTLCache는 심볼별로 따로 캐시합니다. 여러 통화 대시보드에서 5개 심볼을 60s 간격으로 조회하면 캐시가 없을 때 분당 5회, 모두 캐시되어 있을 때 0회의 API 호출이 발생합니다.
# USD spot, defaultspot("XAU-USD-SPOT")spot("XAU-INR-SPOT")spot("XAU-EUR-SPOT")# Silver in USDspot("XAG-USD-SPOT")예상 결과
{ "symbol": "XAU", "quote_currency": "USD", "unit": "troy_ounce", "contract_type": "spot", "price": "4012.75", "is_stale": false, "computed_at": "2026-10-23T07:00:18.221118+00:00"}표준 출력에는 symbol, quote_currency, Decimal 형식의 price, ISO 8601 형식의 computed_at 타임스탬프가 한 줄로 표시됩니다. 이후 코드에서는 TypedDict 응답을 사용합니다.
자주 발생하는 오류
| 코드 | 증상 | 해결 방법 |
|---|---|---|
| 401 | requests.exceptions.HTTPError: 401 Client Error | API 키가 없거나 유효하지 않습니다. echo $GOLDPRICE_API_KEY로 GOLDPRICE_API_KEY 설정을 확인하세요. 비어 있다면 대시보드의 키로 다시 설정하세요. 클라이언트는 호출 시점이 아니라 모듈을 가져올 때 환경 변수 누락을 검사하므로 첫 import goldprice에서 오류가 발생합니다. |
| 429 | RateLimited 재시도가 백오프 후 세 번 모두 실패하고 예외가 발생합니다 | 분당 한도를 모두 사용했습니다. 일정한 반복 조회는 60초 캐시로 방지할 수 있습니다. 서로 다른 심볼 요청이 한꺼번에 몰리면 TTLCache.maxsize를 늘리거나 호출 시점을 분산하세요. 대량 호출을 계속해야 한다면 /pricing에서 유료 플랜을 확인하세요. |
| N/A | 많은 가격을 합산할 때 부동소수점 오차가 누적됩니다 | 계산에는 항상 Decimal을 사용하고 float로 변환하지 마세요. 클라이언트는 가격을 Decimal로 반환합니다. JSON 직렬화 시 float로 바꾸지 말고 str(price)를 사용하면 전송 중에도 정밀도를 유지할 수 있습니다. |
더 활용하기
- 프로세스 간에 캐시를 유지하려면
TTLCache를 Redis 기반 캐시로 바꿔 여러 워커가 메모리의 시세를 공유하게 하세요 /v1/bars?symbol=XAU-USD-SPOT&interval=1d&from=...&to=...용bars()래퍼를 추가하고 백테스트용 pandas DataFrame으로 변환하세요- 비동기 서비스라면
requests를httpx.AsyncClient로 바꾸세요. 응답 구조는 같습니다 - 클라이언트를 FastAPI 엔드포인트에 연결해 Python을 쓰지 않는 내부 서비스에도 제공하세요
- 캐시 적중률, p50/p95 지연 시간, 429 재시도 횟수를 Prometheus 지표로 제공하세요