---
name: api-integration
description: OpenDART API를 통합하고 새로운 API 모듈을 추가하는 방법
---
# API 통합 가이드
## 개요
이 skill은 OpenDART API를 프로젝트에 통합하고, 새로운 API 모듈(ds001~ds006)을 추가하는 방법을 설명합니다.
## 사용 시나리오
- 새로운 OpenDART API 엔드포인트를 추가할 때
- 기존 API 모듈에 새로운 메서드를 추가할 때
- API 응답 변환 로직을 수정할 때
## 구현 가이드
### 1. API 모듈 구조
API 모듈은 `src/mcp_opendart/apis/` 디렉토리에 위치:
```
apis/
├── client.py # OpenDartClient (기본 클라이언트)
├── ds001.py # 공시정보 API
├── ds002.py # 정기보고서 주요정보 API
├── ds003.py # 정기보고서 재무정보 API
├── ds004.py # 지분공시 종합정보 API
├── ds005.py # 주요사항보고서 주요정보 API
└── ds006.py # 증권신고서 주요정보 API
```
### 2. API 클래스 구조
각 API 모듈은 `OpenDartClient`를 받아서 초기화:
```python
from typing import Dict, Any, Optional
from ..apis.client import OpenDartClient
class DisclosureAPI:
"""DS001 - 공시정보 API"""
def __init__(self, client: OpenDartClient):
self.client = client
def get_something(self, param: str) -> Dict[str, Any]:
"""
API 메서드 설명
"""
endpoint = "endpoint/path"
params = {
"param_name": param
}
response = self.client._make_request(endpoint, params)
# 응답 처리
if response.get("status") == "000":
return {
"status": "000",
"message": "정상",
"data": response.get("list", [])
}
else:
return {
"status": response.get("status", "500"),
"message": response.get("message", "오류 발생")
}
```
### 3. OpenDartClient 사용
`OpenDartClient`는 모든 API 요청의 기반:
```python
# _make_request 메서드 사용
response = self.client._make_request(
endpoint="endpoint/path",
params={"param": "value"},
method="GET" # 또는 "POST"
)
```
### 4. 응답 형식
모든 API 메서드는 일관된 형식 반환:
```python
{
"status": "000", # "000" = 성공, 그 외 = 에러
"message": "정상",
"data": [...] # 실제 데이터
}
```
### 5. 서버에 API 모듈 등록
새 API 모듈을 추가하려면 `server.py` 수정:
```python
# 1. Import 추가
from .apis import ds001, ds002, ds003, ds004, ds005, ds006, ds007 # 새 모듈
# 2. OpenDartContext에 추가
@dataclass
class OpenDartContext:
client: OpenDartClient
ds001: Any
ds002: Any
# ...
ds007: Any # 새 모듈
# 3. opendart_lifespan에서 초기화
ctx = OpenDartContext(
client=client,
ds001=ds001.DisclosureAPI(client),
# ...
ds007=ds007.NewAPI(client), # 새 모듈
)
```
## 예제
### 예제 1: 간단한 GET 요청
```python
def get_corporation_info(self, corp_code: str) -> Dict[str, Any]:
"""
기업 개황정보 조회
"""
endpoint = "company.json"
params = {
"corp_code": corp_code
}
response = self.client._make_request(endpoint, params)
if response.get("status") == "000":
return {
"status": "000",
"message": "정상",
"data": response.get("list", [])
}
else:
return {
"status": response.get("status", "500"),
"message": response.get("message", "오류 발생")
}
```
### 예제 2: POST 요청 및 파일 다운로드
```python
def get_disclosure_document(self, rcp_no: str) -> Dict[str, Any]:
"""
공시서류 원본파일 다운로드
"""
endpoint = "document.xml"
params = {
"rcept_no": rcp_no
}
# POST 요청으로 파일 다운로드
response = self.client._make_request(endpoint, params, method="POST")
if response.get("status") == "000":
# 파일 저장 로직
# ...
return {
"status": "000",
"message": "정상",
"file_path": saved_path
}
else:
return {
"status": response.get("status", "500"),
"message": response.get("message", "다운로드 실패")
}
```
### 예제 3: 로컬 캐시 사용
```python
def get_corporation_code_by_name(self, corp_name: str) -> Dict[str, Any]:
"""
기업명으로 고유번호 검색 (로컬 XML 사용)
"""
from ..utils.corp_code_search import read_local_xml, parse_corp_code_xml, search_corporations
try:
xml_content = read_local_xml() # utils/data/CORPCODE.xml 읽기
corporations = parse_corp_code_xml(xml_content)
results = search_corporations(corporations, corp_name)
return {
"status": "000",
"message": "정상",
"items": results
}
except FileNotFoundError:
return {
"status": "400",
"message": "CORPCODE.xml 파일이 없습니다."
}
```
## 응답 변환
### KEY_MAPPING 활용
`ctx_helper.py`의 `KEY_MAPPING`을 통해 응답 키를 human-readable로 변환:
```python
# 자동 변환됨 (with_context 사용 시)
# "corp_name" -> "corporation_name"
# "rcept_no" -> "receipt_number"
# "thstrm_amount" -> "this_term_amount" (숫자형으로도 변환)
```
### 금액 필드 변환
`AMOUNT_FIELDS`에 정의된 필드는 자동으로 숫자형으로 변환:
```python
# "1,234,567" -> 1234567
# "-" -> 0
# "(1,234)" -> -1234
```
## 주의사항
1. **에러 처리**
- 모든 API 호출에 try-except 사용
- OpenDART API 응답 형식 확인 (status, message)
- 네트워크 에러 처리
2. **API 키 관리**
- `OpenDartClient`가 자동으로 API 키 추가
- 환경변수 `OPENDART_API_KEY` 필수
3. **Rate Limiting**
- OpenDART API는 일 20,000회 제한
- 필요시 클라이언트에 rate limiting 로직 추가
4. **응답 형식 일관성**
- 모든 메서드는 `Dict[str, Any]` 반환
- status, message 필드 필수
- data 필드는 실제 데이터 구조에 맞게
5. **캐시 활용**
- 자주 조회되는 데이터는 캐시 사용 고려
- `utils/data/` 디렉토리 활용
## 관련 파일
- [src/mcp_opendart/apis/client.py](src/mcp_opendart/apis/client.py) - OpenDartClient
- [src/mcp_opendart/apis/ds001.py](src/mcp_opendart/apis/ds001.py) - 공시정보 API 예제
- [src/mcp_opendart/server.py](src/mcp_opendart/server.py) - API 모듈 등록
- [src/mcp_opendart/utils/ctx_helper.py](src/mcp_opendart/utils/ctx_helper.py) - 응답 변환