ecos-reader 프로젝트에 기여해주셔서 감사합니다! 이 문서는 프로젝트에 기여하는 방법을 안내합니다.
- 버그 리포트: Issues에서 버그 제보
- 기능 제안: 새로운 지표나 기능 제안
- 문서 개선: 오타 수정, 예제 추가, 설명 개선
- 코드 기여: 새로운 지표 구현, 버그 수정, 성능 개선
- 테스트 추가: 테스트 커버리지 향상
- IMPLEMENTATION_STATUS.md에서 구현 현황 확인
- Issues에서 중복 여부 확인
- 작업하고 싶은 내용이 있다면 Issue를 먼저 생성하여 논의
# Repository Fork (GitHub에서)
# https://github.com/choo121600/ecos-reader -> Fork 버튼 클릭
# Clone
git clone https://github.com/YOUR_USERNAME/ecos-reader.git
cd ecos-reader
# Upstream 설정
git remote add upstream https://github.com/choo121600/ecos-reader.git필수 요구사항: Python 3.10 이상
# Virtual environment 생성
python -m venv .venv
# Activate
# macOS/Linux:
source .venv/bin/activate
# Windows:
.venv\Scripts\activate
# 개발 의존성 설치
pip install -e ".[dev]"# Pre-commit hooks 설치
pre-commit install
# 수동으로 실행해보기
pre-commit run --all-filesPre-commit hooks는 다음을 자동으로 체크합니다:
- 코드 포맷팅 (ruff-format)
- 린팅 (ruff)
- 타입 체킹 (mypy)
- 파일 끝 공백 제거
- YAML/TOML 문법 체크
# .env 파일 생성
echo "ECOS_API_KEY=your_api_key_here" > .env
# 또는 환경 변수로 설정
export ECOS_API_KEY="your_api_key_here"API 키 발급: https://ecos.bok.or.kr/api/
ecos-reader/
├── src/ecos/
│ ├── __init__.py # Public API
│ ├── client.py # ECOS API 클라이언트
│ ├── config.py # 설정 관리
│ ├── cache.py # 캐싱 레이어
│ ├── parser.py # 응답 파싱
│ ├── constants.py # 통계코드 상수
│ ├── exceptions.py # 예외 클래스
│ └── indicators/ # 지표 모듈
│ ├── __init__.py
│ ├── interest_rate.py # 금리 지표
│ ├── prices.py # 물가 지표
│ ├── growth.py # 성장 지표
│ └── money.py # 통화 지표
├── tests/
│ ├── test_client.py
│ ├── test_e2e.py # Low-level API E2E 테스트
│ └── test_e2e_indicators.py # High-level 지표 E2E 테스트
└── docs/ # 문서
프로젝트는 다음 도구들을 사용합니다:
- ruff: 린팅 및 포맷팅
- mypy: 정적 타입 체킹
- pytest: 테스팅
모든 함수에 타입 힌트를 추가해야 합니다:
from __future__ import annotations
import pandas as pd
def get_indicator(
start_date: str | None = None,
end_date: str | None = None,
) -> pd.DataFrame:
"""
지표를 조회합니다.
Parameters
----------
start_date : str, optional
조회 시작일
end_date : str, optional
조회 종료일
Returns
-------
pd.DataFrame
조회된 데이터
"""
passNumPy 스타일 docstring을 사용합니다:
def function_name(param1: str, param2: int) -> bool:
"""
간단한 함수 설명 (한 줄)
더 자세한 설명이 필요하면 여기에 작성합니다.
Parameters
----------
param1 : str
첫 번째 파라미터 설명
param2 : int
두 번째 파라미터 설명
Returns
-------
bool
반환값 설명
Examples
--------
>>> result = function_name("test", 42)
>>> print(result)
True
Notes
-----
추가 참고사항이 있으면 여기에 작성
"""
passimport ecos
# API 키 설정
ecos.set_api_key("your_api_key")
# 통계표 목록 조회
client = ecos.EcosClient()
tables = client.get_statistic_table_list(start=1, end=1000)
# 원하는 통계 검색
# 예: "환율" 검색
import pandas as pd
df = ecos.parser.parse_response(tables)
exchange_rate = df[df['stat_name'].str.contains('환율', na=False)]
print(exchange_rate[['stat_code', 'stat_name']])
# 항목 코드 확인
items = client.get_statistic_item_list(stat_code='731Y003')
df_items = ecos.parser.parse_response(items)
print(df_items[['item_code', 'item_name']].head())src/ecos/constants.py에 통계코드와 항목코드를 추가합니다:
# ============================================================================
# 환율 지표 (forex)
# ============================================================================
STAT_EXCHANGE_RATE = "731Y003"
# 통화별 항목코드
EXCHANGE_RATE_ITEMS: dict[str, str] = {
"USD": "0000001", # 원/달러
"JPY": "0000002", # 원/100엔
"EUR": "0000003", # 원/유로
"CNY": "0000053", # 원/위안
}적절한 카테고리 파일에 함수를 추가합니다 (예: src/ecos/indicators/forex.py):
"""
환율 지표 모듈
주요 통화의 환율 정보를 조회합니다.
"""
from __future__ import annotations
from datetime import datetime
from typing import Literal
import pandas as pd
from ..client import get_client
from ..constants import (
EXCHANGE_RATE_ITEMS,
PERIOD_DAILY,
STAT_EXCHANGE_RATE,
)
from ..parser import normalize_stat_result, parse_response
def get_exchange_rate(
currency: Literal["USD", "JPY", "EUR", "CNY"] = "USD",
start_date: str | None = None,
end_date: str | None = None,
) -> pd.DataFrame:
"""
주요 통화의 환율을 조회합니다.
Parameters
----------
currency : str
조회할 통화
- 'USD': 미국 달러 (기본값)
- 'JPY': 일본 엔
- 'EUR': 유럽 유로
- 'CNY': 중국 위안
start_date : str, optional
조회 시작일 (YYYYMMDD 형식), 기본값: 1년 전
end_date : str, optional
조회 종료일 (YYYYMMDD 형식), 기본값: 현재
Returns
-------
pd.DataFrame
컬럼: date, value, unit
- date: 날짜 (datetime)
- value: 환율
- unit: 단위
Examples
--------
>>> import ecos
>>> df = ecos.get_exchange_rate(currency="USD")
>>> df.head()
date value unit
0 2024-01-01 1200.5 원/USD
>>> df = ecos.get_exchange_rate(currency="JPY")
"""
if currency not in EXCHANGE_RATE_ITEMS:
raise ValueError(
f"currency는 {list(EXCHANGE_RATE_ITEMS.keys())} 중 하나여야 합니다."
)
# 기본 날짜 설정
if start_date is None or end_date is None:
end_dt = datetime.now()
start_dt = datetime(end_dt.year - 1, end_dt.month, end_dt.day)
start_date = start_date or start_dt.strftime("%Y%m%d")
end_date = end_date or end_dt.strftime("%Y%m%d")
item_code = EXCHANGE_RATE_ITEMS[currency]
client = get_client()
response = client.get_statistic_search(
stat_code=STAT_EXCHANGE_RATE,
period=PERIOD_DAILY,
start_date=start_date,
end_date=end_date,
item_code1=item_code,
)
df = parse_response(response)
return normalize_stat_result(df)src/ecos/indicators/__init__.py:
from .forex import get_exchange_rate
__all__ = [
# ... 기존 함수들
"get_exchange_rate",
]src/ecos/__init__.py:
from .indicators import (
# ... 기존 함수들
get_exchange_rate,
)
__all__ = [
# ... 기존 함수들
"get_exchange_rate",
]tests/test_forex.py 생성:
"""환율 지표 유닛 테스트"""
import pandas as pd
import pytest
from ecos.indicators.forex import get_exchange_rate
class TestExchangeRate:
"""환율 조회 테스트"""
def test_get_exchange_rate_usd(self, mock_client):
"""USD 환율 조회"""
df = get_exchange_rate(currency="USD")
assert isinstance(df, pd.DataFrame)
assert "date" in df.columns
assert "value" in df.columns
def test_invalid_currency(self):
"""잘못된 통화 코드"""
with pytest.raises(ValueError, match="currency는"):
get_exchange_rate(currency="INVALID")tests/test_e2e_indicators.py에 추가:
class TestE2EForexIndicators:
"""환율 지표 E2E 테스트"""
def test_get_exchange_rate_usd(self):
"""USD 환율 조회"""
df = ecos.get_exchange_rate(
currency="USD",
start_date="20230101",
end_date="20231231"
)
assert not df.empty
assert "date" in df.columns
assert "value" in df.columns
assert "unit" in df.columns
assert len(df) > 0
def test_get_exchange_rate_jpy(self):
"""JPY 환율 조회"""
df = ecos.get_exchange_rate(currency="JPY")
assert not df.empty
assert len(df) > 0# 전체 테스트
pytest
# 특정 파일만
pytest tests/test_forex.py -v
# E2E 테스트 (API 키 필요)
export ECOS_API_KEY="your_key"
pytest tests/test_e2e_indicators.py::TestE2EForexIndicators -v
# 커버리지 확인
pytest --cov=src/ecos --cov-report=html# Main branch를 최신으로 업데이트
git checkout main
git pull upstream main
# Feature branch 생성
git checkout -b feature/add-exchange-rate-indicatorBranch 이름 규칙:
feature/: 새로운 기능fix/: 버그 수정docs/: 문서 개선test/: 테스트 추가/수정refactor/: 리팩토링
# 변경된 파일 확인
git status
# 파일 추가
git add src/ecos/indicators/forex.py
git add src/ecos/constants.py
git add tests/test_e2e_indicators.py
# 커밋 (pre-commit hooks가 자동 실행됨)
git commit -m "Add exchange rate indicator (get_exchange_rate)"# Fork한 repository에 push
git push origin feature/add-exchange-rate-indicatorGitHub에서:
- Fork한 repository로 이동
- "Compare & pull request" 버튼 클릭
- PR 템플릿에 따라 설명 작성:
## 변경 내용
환율 지표 조회 기능을 추가했습니다.
## 구현 사항
- [ ] `get_exchange_rate()` 함수 구현
- [ ] USD, JPY, EUR, CNY 지원
- [ ] E2E 테스트 추가
- [ ] 문서 업데이트
## 테스트
- [x] Unit tests 통과
- [x] E2E tests 통과
- [x] Pre-commit hooks 통과
## 관련 Issue
Closes #123
## 스크린샷
```python
>>> df = ecos.get_exchange_rate(currency="USD")
>>> df.head()
date value unit
0 2024-01-01 1200.5 원/USD제출 전 확인:
- 모든 테스트 통과 (
pytest) - 타입 체크 통과 (
mypy src/ecos) - 린팅 통과 (
ruff check src/ecos) - 포맷팅 적용 (
ruff format src/ecos) - Docstring 작성 (NumPy 스타일)
- E2E 테스트 추가
-
__all__업데이트 - CHANGELOG.md 업데이트 (메인테이너가 할 수도 있음)
A: IMPLEMENTATION_STATUS.md의 우선순위를 참고하세요:
- 🔴 우선순위 1: 환율 및 국제수지
- 🟡 우선순위 2: 실물경제 및 심리지표
- 🟢 우선순위 3: 기타 중요 통계
A: 네! 다음 방법으로 기여 가능합니다:
- 문서 개선
- 코드 리팩토링
- 타입 힌트 추가
- Unit test 작성 (mock 사용)
A: Issue를 생성해주세요! 버그 리포트만으로도 큰 도움이 됩니다.
A: 다음 도구를 활용하세요:
ecos_all_statistics.csv파일 참조- ECOS 공식 홈페이지에서 검색
- Issue에 질문 남기기
- 질문: GitHub Discussions
- 버그: GitHub Issues
- 기타: Repository 메인테이너에게 연락