콘텐츠로 건너뛰기

7-3. REST API 금융 데이터 수집

  • 기준

금융 데이터 제공업체(이하 FDP)를 선정 하였으면 “바이낸스야 오늘 비트코인 가격을 알려줘”라고 요청하는 명령어가 있는 코드를 작성해야 됩니다.

보통 이렇게 어떤 목적이 있는 요청을 모아놓은 파일의 이름을 클라이언트라고 하고 외부에 요청하기 때문에”backend/app/external_apis/”라는 폴더를 만들어파일을 넣는 것이 직관적입니다.

다만 향후 추가적으로 위에서 나열한 여러 FDP를 추가 할수 있기에 반복되는 요청 내용을 모아놓은 베이스 그릇(이를 BaseClient)을 만들고 각각의 클라이언트는 BaseClient를 가져와서 이름만 변경하고 각자에 맞는 내용만 추가하면 되는 이런 로직으로 구성하겠습니다.

external_apis/ ├── base_client/ │   ├── base_client.py └── implementations/     ├── binance_client.py     └── fmp_client.py

BaseClient 필수 내용

이러한 외부 FDP에서 데이터를 안전하게 가져오기 위한 똑똑한 이 배달원 BaseClient에는 갖춰야 할 가장 기본적인 3가지 필수 능력이 있습니다.

하나, 처음 시도후 안되면 다시 요청(재시도 기능)

FDP는 수많은 요청에 대해 순차적으로 답을 합니다. 따라서 가끔 요청을 안 받거나 바빠서 응답이 늦을 때가 있습니다. 이때 아무리 우리 배달원이 똑똑해도 그냥 포기하고 돌아오게 되며 우린 그 답을 알수 없게 됩니다.

그러나 이러한 재시도 가능 기능을 넣으면 “1초 뒤에 다시 걸어보고, 또 안 받으면 2초 뒤에 다시 걸어보는” 끈기를 발휘해 앱이 뻗지 않게 지켜줍니다.

둘, 너무 많은 요청은 무료 사용에 제한이 있음(요청 속도 조절)

금융 데이터 제공 업체별 REST API 제한이 있습니다. 무료로 사용하면서 무제한으로 사용한다는 것은 너무 많은것을 바라는 것이죠!

또한 FDP에서 제공하는 제한이상으로 사용하면 그 계정은 차단해 버립니다. (Rate Limit)

그래서 BaseClient는 한 번에 우르르 몰려가서 요청하지 않게 알아서 1초에 한 번씩 줄을 서서 질서 있게 주문하도록 속도를 조절해 줍니다.

셋, 수신되는 데이터 형식 통일 (응답 표준화)

코인, 주식 등 각 자산별 FDP마다 데이터를 담아주는 데이터 형식(Json 형식 등)이 다 다릅니다. 이걸 그대로 프론트엔드에 던져주면 FDP별, 데이터별로 매번 새로 형식을 조정해야 됨으로 비효율의 극치입니다.

어디서 어떤 데이터든 상관없이, 성공했을 때는 {“성공”: 맞음, “데이터”: …}처럼 우리 식당만의 똑같은 규격 상자에 예쁘게 담아서 전달해야 합니다.

🤖 실전! BaseClient 추가(2-2)

🧠 이번 실습은 자산별 가격 데이터 수집의 근간이 되는 BaseClient를 만들고 이후 다른 Client가 추가되거나 데이터 형식이 달라도 형식이 통일되게 만드는 과정입니다.

✨ 사용자의 의도(Vibe)

“외부 금융 데이터 제공업체에서 데이터를 수집할 때 사용할 기본 통신 뼈대 클래스인 BaseClient를 파이썬으로 작성해 줘. 파일 경로는 backend/app/external_apis/base/base_client.py로 해주고, 다음 3가지 핵심 기능을 반드시 포함해 줘.

  1. 비동기 통신 및 재시도 기능: httpx.AsyncClient를 사용해서 비동기로 통신하고, 에러가 나면 tenacity 라이브러리를 사용해서 대기 시간을 점점 늘려가며(지수 백오프) 최대 3번까지 재시도하게 만들어 줘.
  2. 요청 속도 조절 기능: API 제공자에게 차단당하지 않도록 asyncio.Semaphore와 asyncio.sleep()을 사용해서 한 번에 처리하는 요청 수를 제한하고, 요청 사이에 대기 시간을 둬 줘.
  3. 응답 표준화: API 요청이 성공하든 실패하든 항상 {“success”: True/False, “data”: 데이터, “error”: 에러메시지} 형식의 딕셔너리로 똑같이 반환하도록 만들어 줘.

그리고 초보자가 이해하기 쉽도록 각 기능이 왜 필요한지 한글 주석을 상세하게 달아줘.”

💻 AI가 생성한 코드 (Syntax)

import asyncioimport loggingfrom typing import Any, Dict, Optionalimport httpxfrom tenacity import (    AsyncRetrying,    retry_if_exception_type,    stop_after_attempt,    wait_exponential,)logger = logging.getLogger(__name__)class BaseClient:    """    외부 API와 통신하기 위한 기본 클라이언트 클래스입니다.    이 클래스를 상속받아 각 데이터 제공업체(예: Binance, Upbit 등)에 맞는 구체적인 클라이언트를 구현합니다.    """
def __init__(        self,        base_url: str,        max_concurrent_requests: int = 5,        request_delay: float = 0.5,        timeout: float = 10.0,    ): 이하 생략 …
return await self._make_request("POST", endpoint, headers=headers, data=data)

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다