ecos-reader 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ecos/__init__.py +109 -0
- ecos/cache.py +212 -0
- ecos/client.py +394 -0
- ecos/config.py +148 -0
- ecos/constants.py +155 -0
- ecos/exceptions.py +73 -0
- ecos/indicators/__init__.py +29 -0
- ecos/indicators/growth.py +186 -0
- ecos/indicators/interest_rate.py +226 -0
- ecos/indicators/money.py +173 -0
- ecos/indicators/prices.py +206 -0
- ecos/logging.py +205 -0
- ecos/metrics.py +247 -0
- ecos/parser.py +197 -0
- ecos/py.typed +0 -0
- ecos/types.py +84 -0
- ecos_reader-0.1.0.dist-info/METADATA +286 -0
- ecos_reader-0.1.0.dist-info/RECORD +20 -0
- ecos_reader-0.1.0.dist-info/WHEEL +4 -0
- ecos_reader-0.1.0.dist-info/licenses/LICENSE +21 -0
ecos/config.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ecos-reader 설정 관리
|
|
3
|
+
|
|
4
|
+
API Key 및 기본 설정을 관리합니다.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
from .exceptions import EcosConfigError
|
|
12
|
+
|
|
13
|
+
# dotenv 로드 상태(명시적으로만 로드)
|
|
14
|
+
_dotenv_loaded: bool = False
|
|
15
|
+
|
|
16
|
+
# 전역 API Key 저장소
|
|
17
|
+
_api_key: str | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def load_env(*, dotenv_path: str | None = None, override: bool = False) -> bool:
|
|
21
|
+
"""
|
|
22
|
+
.env 파일을 명시적으로 로드합니다.
|
|
23
|
+
|
|
24
|
+
Notes
|
|
25
|
+
-----
|
|
26
|
+
라이브러리 import 시점에 자동으로 .env를 로드하지 않습니다.
|
|
27
|
+
필요 시 사용자가 직접 호출하여 환경 변수를 로드할 수 있습니다.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
dotenv_path : str, optional
|
|
32
|
+
.env 파일 경로. 미지정 시 python-dotenv 기본 탐색 규칙을 따릅니다.
|
|
33
|
+
override : bool, optional
|
|
34
|
+
이미 설정된 환경 변수를 덮어쓸지 여부
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
bool
|
|
39
|
+
.env 파일을 로드했으면 True, 아니면 False
|
|
40
|
+
"""
|
|
41
|
+
global _dotenv_loaded
|
|
42
|
+
try:
|
|
43
|
+
from dotenv import load_dotenv
|
|
44
|
+
except ImportError:
|
|
45
|
+
# python-dotenv가 설치되어 있지 않은 경우
|
|
46
|
+
_dotenv_loaded = False
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
loaded = load_dotenv(dotenv_path=dotenv_path, override=override)
|
|
50
|
+
_dotenv_loaded = bool(loaded)
|
|
51
|
+
return _dotenv_loaded
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def set_api_key(api_key: str) -> None:
|
|
55
|
+
"""
|
|
56
|
+
API Key를 설정합니다.
|
|
57
|
+
|
|
58
|
+
Parameters
|
|
59
|
+
----------
|
|
60
|
+
api_key : str
|
|
61
|
+
한국은행에서 발급받은 ECOS Open API 인증키
|
|
62
|
+
|
|
63
|
+
Examples
|
|
64
|
+
--------
|
|
65
|
+
>>> import ecos
|
|
66
|
+
>>> ecos.set_api_key("your_api_key")
|
|
67
|
+
"""
|
|
68
|
+
global _api_key
|
|
69
|
+
if not api_key or not isinstance(api_key, str):
|
|
70
|
+
raise EcosConfigError("API Key는 빈 문자열이 아닌 문자열이어야 합니다.")
|
|
71
|
+
_api_key = api_key
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def get_api_key() -> str:
|
|
75
|
+
"""
|
|
76
|
+
현재 설정된 API Key를 반환합니다.
|
|
77
|
+
|
|
78
|
+
환경 변수 `ECOS_API_KEY`가 설정되어 있으면 해당 값을 사용합니다.
|
|
79
|
+
`set_api_key()`로 직접 설정한 값이 있으면 해당 값을 우선합니다.
|
|
80
|
+
`.env` 파일은 import 시점에 자동으로 로드되지 않습니다(필요 시 `load_env()` 호출).
|
|
81
|
+
|
|
82
|
+
Returns
|
|
83
|
+
-------
|
|
84
|
+
str
|
|
85
|
+
ECOS API 인증키
|
|
86
|
+
|
|
87
|
+
Raises
|
|
88
|
+
------
|
|
89
|
+
EcosConfigError
|
|
90
|
+
API Key가 설정되지 않은 경우
|
|
91
|
+
|
|
92
|
+
Examples
|
|
93
|
+
--------
|
|
94
|
+
>>> import ecos
|
|
95
|
+
>>> ecos.set_api_key("your_api_key")
|
|
96
|
+
>>> ecos.get_api_key()
|
|
97
|
+
'your_api_key'
|
|
98
|
+
"""
|
|
99
|
+
global _api_key
|
|
100
|
+
|
|
101
|
+
# 직접 설정한 값 우선
|
|
102
|
+
if _api_key is not None:
|
|
103
|
+
return _api_key
|
|
104
|
+
|
|
105
|
+
# 환경 변수에서 로드
|
|
106
|
+
env_key = os.environ.get("ECOS_API_KEY")
|
|
107
|
+
if env_key:
|
|
108
|
+
return env_key
|
|
109
|
+
|
|
110
|
+
raise EcosConfigError(
|
|
111
|
+
"API Key가 설정되지 않았습니다. "
|
|
112
|
+
"환경 변수 ECOS_API_KEY를 설정하거나, "
|
|
113
|
+
"ecos.load_env()로 .env 파일을 로드하거나, "
|
|
114
|
+
"ecos.set_api_key('your_api_key')를 호출하세요. "
|
|
115
|
+
"API Key는 https://ecos.bok.or.kr/api/ 에서 신청할 수 있습니다."
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def clear_api_key() -> None:
|
|
120
|
+
"""
|
|
121
|
+
설정된 API Key를 초기화합니다.
|
|
122
|
+
|
|
123
|
+
주로 테스트 목적으로 사용됩니다.
|
|
124
|
+
"""
|
|
125
|
+
global _api_key
|
|
126
|
+
_api_key = None
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# 기본 설정값
|
|
130
|
+
class Settings:
|
|
131
|
+
"""기본 설정값"""
|
|
132
|
+
|
|
133
|
+
# API 기본값
|
|
134
|
+
BASE_URL: str = "https://ecos.bok.or.kr/api/"
|
|
135
|
+
DEFAULT_FORMAT: str = "json"
|
|
136
|
+
DEFAULT_LANG: str = "kr"
|
|
137
|
+
|
|
138
|
+
# 요청 설정
|
|
139
|
+
DEFAULT_TIMEOUT: int = 30 # 초
|
|
140
|
+
MAX_RETRIES: int = 3
|
|
141
|
+
RETRY_BACKOFF_FACTOR: float = 1.0
|
|
142
|
+
|
|
143
|
+
# 캐시 설정
|
|
144
|
+
CACHE_TTL: int = 3600 # 1시간
|
|
145
|
+
CACHE_MAXSIZE: int = 100
|
|
146
|
+
|
|
147
|
+
# 페이지네이션
|
|
148
|
+
DEFAULT_PAGE_SIZE: int = 10000
|
ecos/constants.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ecos-reader 상수 정의
|
|
3
|
+
|
|
4
|
+
ECOS API 통계코드 및 항목코드를 정의합니다.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
# ============================================================================
|
|
10
|
+
# 주기 코드
|
|
11
|
+
# ============================================================================
|
|
12
|
+
|
|
13
|
+
PERIOD_DAILY = "D"
|
|
14
|
+
PERIOD_MONTHLY = "M"
|
|
15
|
+
PERIOD_QUARTERLY = "Q"
|
|
16
|
+
PERIOD_ANNUAL = "A"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# ============================================================================
|
|
20
|
+
# 금리 지표 (interest_rate)
|
|
21
|
+
# ============================================================================
|
|
22
|
+
|
|
23
|
+
# 한국은행 기준금리
|
|
24
|
+
STAT_BASE_RATE = "722Y001"
|
|
25
|
+
ITEM_BASE_RATE = "0101000"
|
|
26
|
+
|
|
27
|
+
# 시장금리 (국고채, 회사채 등)
|
|
28
|
+
STAT_MARKET_RATE = "817Y002"
|
|
29
|
+
|
|
30
|
+
# 국고채 만기별 항목코드
|
|
31
|
+
TREASURY_YIELD_ITEMS: dict[str, str] = {
|
|
32
|
+
"1Y": "010190000", # 국고채 1년
|
|
33
|
+
"3Y": "010200000", # 국고채 3년
|
|
34
|
+
"5Y": "010200001", # 국고채 5년
|
|
35
|
+
"10Y": "010210000", # 국고채 10년
|
|
36
|
+
"20Y": "010220000", # 국고채 20년
|
|
37
|
+
"30Y": "010230000", # 국고채 30년
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# ============================================================================
|
|
42
|
+
# 물가 지표 (prices)
|
|
43
|
+
# ============================================================================
|
|
44
|
+
|
|
45
|
+
# 소비자물가지수 (전년동월비)
|
|
46
|
+
STAT_CPI = "901Y009"
|
|
47
|
+
ITEM_CPI_TOTAL = "0" # 총지수
|
|
48
|
+
|
|
49
|
+
# 근원 소비자물가지수
|
|
50
|
+
STAT_CORE_CPI = "901Y010"
|
|
51
|
+
ITEM_CORE_CPI = "AA0000" # 농산물및석유류제외
|
|
52
|
+
|
|
53
|
+
# 생산자물가지수
|
|
54
|
+
STAT_PPI = "404Y014"
|
|
55
|
+
ITEM_PPI_TOTAL = "A00" # 총지수
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# ============================================================================
|
|
59
|
+
# 성장 지표 (growth)
|
|
60
|
+
# ============================================================================
|
|
61
|
+
|
|
62
|
+
# GDP (국내총생산)
|
|
63
|
+
STAT_GDP_REAL = "200Y001" # 실질 GDP
|
|
64
|
+
STAT_GDP_NOMINAL = "200Y002" # 명목 GDP
|
|
65
|
+
ITEM_GDP = "10101" # 국내총생산
|
|
66
|
+
|
|
67
|
+
# GDP 디플레이터
|
|
68
|
+
STAT_GDP_DEFLATOR = "200Y004"
|
|
69
|
+
ITEM_GDP_DEFLATOR = "10101"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# ============================================================================
|
|
73
|
+
# 통화 지표 (money)
|
|
74
|
+
# ============================================================================
|
|
75
|
+
|
|
76
|
+
# 통화량
|
|
77
|
+
STAT_MONEY_SUPPLY = "101Y018"
|
|
78
|
+
|
|
79
|
+
# 통화량 항목코드
|
|
80
|
+
MONEY_SUPPLY_ITEMS: dict[str, str] = {
|
|
81
|
+
"M1": "BBGA00", # 협의통화(M1)
|
|
82
|
+
"M2": "BBGS00", # 광의통화(M2)
|
|
83
|
+
"Lf": "BBLA00", # 금융기관유동성(Lf)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# 은행 대출
|
|
87
|
+
STAT_BANK_LENDING = "104Y016"
|
|
88
|
+
|
|
89
|
+
# 대출 부문별 항목코드
|
|
90
|
+
BANK_LENDING_ITEMS: dict[str, str] = {
|
|
91
|
+
"all": "BDCA", # 총대출
|
|
92
|
+
"household": "BDCB", # 가계대출
|
|
93
|
+
"corporate": "BDCC", # 기업대출
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# ============================================================================
|
|
98
|
+
# 환율 지표 (forex) - Phase 3
|
|
99
|
+
# ============================================================================
|
|
100
|
+
|
|
101
|
+
STAT_EXCHANGE_RATE = "731Y003"
|
|
102
|
+
|
|
103
|
+
# 통화별 항목코드
|
|
104
|
+
EXCHANGE_RATE_ITEMS: dict[str, str] = {
|
|
105
|
+
"USD": "0000001", # 원/달러
|
|
106
|
+
"JPY": "0000002", # 원/100엔
|
|
107
|
+
"EUR": "0000003", # 원/유로
|
|
108
|
+
"CNY": "0000053", # 원/위안
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# 실효환율
|
|
112
|
+
STAT_EFFECTIVE_RATE = "731Y004"
|
|
113
|
+
ITEM_NEER = "0000001" # 명목실효환율
|
|
114
|
+
ITEM_REER = "0000002" # 실질실효환율
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# ============================================================================
|
|
118
|
+
# 국제수지 지표 (bop) - Phase 3
|
|
119
|
+
# ============================================================================
|
|
120
|
+
|
|
121
|
+
STAT_BOP = "301Y017"
|
|
122
|
+
ITEM_CURRENT_ACCOUNT = "CA" # 경상수지
|
|
123
|
+
ITEM_CAPITAL_ACCOUNT = "KA" # 자본수지
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# ============================================================================
|
|
127
|
+
# 실물 지표 (real_economy) - Phase 4
|
|
128
|
+
# ============================================================================
|
|
129
|
+
|
|
130
|
+
# 산업생산지수
|
|
131
|
+
STAT_INDUSTRIAL_PRODUCTION = "901Y033"
|
|
132
|
+
ITEM_INDUSTRIAL_PRODUCTION = "A00"
|
|
133
|
+
|
|
134
|
+
# 설비투자지수
|
|
135
|
+
STAT_FACILITY_INVESTMENT = "901Y049"
|
|
136
|
+
ITEM_FACILITY_INVESTMENT = "I16A"
|
|
137
|
+
|
|
138
|
+
# 소매판매지수
|
|
139
|
+
STAT_RETAIL_SALES = "901Y037"
|
|
140
|
+
ITEM_RETAIL_SALES = "*"
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# ============================================================================
|
|
144
|
+
# 심리 지표 (sentiment) - Phase 4
|
|
145
|
+
# ============================================================================
|
|
146
|
+
|
|
147
|
+
# 기업경기실사지수 (BSI)
|
|
148
|
+
STAT_BSI = "512Y014"
|
|
149
|
+
ITEM_BSI_MANUFACTURING = "A001"
|
|
150
|
+
ITEM_BSI_NON_MANUFACTURING = "B001"
|
|
151
|
+
ITEM_BSI_ALL = "C001"
|
|
152
|
+
|
|
153
|
+
# 소비자심리지수 (CSI)
|
|
154
|
+
STAT_CSI = "511Y002"
|
|
155
|
+
ITEM_CSI = "FME"
|
ecos/exceptions.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ecos-reader 예외 클래스 정의
|
|
3
|
+
|
|
4
|
+
ECOS API 에러 및 라이브러리 예외를 처리합니다.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EcosError(Exception):
|
|
11
|
+
"""ecos-reader 기본 예외"""
|
|
12
|
+
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class EcosAPIError(EcosError):
|
|
17
|
+
"""ECOS API 호출 에러
|
|
18
|
+
|
|
19
|
+
Attributes
|
|
20
|
+
----------
|
|
21
|
+
code : str
|
|
22
|
+
ECOS API 에러 코드
|
|
23
|
+
message : str
|
|
24
|
+
에러 메시지
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, code: str, message: str):
|
|
28
|
+
self.code = code
|
|
29
|
+
self.message = message
|
|
30
|
+
super().__init__(f"[{code}] {message}")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class EcosConfigError(EcosError):
|
|
34
|
+
"""설정 관련 에러 (API Key 등)"""
|
|
35
|
+
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class EcosNetworkError(EcosError):
|
|
40
|
+
"""네트워크 연결 에러"""
|
|
41
|
+
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class EcosRateLimitError(EcosError):
|
|
46
|
+
"""Rate Limit 초과"""
|
|
47
|
+
|
|
48
|
+
def __init__(self, message: str, code: str = "602"):
|
|
49
|
+
self.code = code
|
|
50
|
+
self.message = message
|
|
51
|
+
super().__init__(f"[{code}] {message}")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ECOS 에러 코드 매핑
|
|
55
|
+
ECOS_ERROR_CODES: dict[str, tuple[type[EcosError], str]] = {
|
|
56
|
+
# 정보 코드
|
|
57
|
+
"INFO_100": (EcosConfigError, "인증키가 유효하지 않습니다."),
|
|
58
|
+
"INFO_200": (EcosAPIError, "해당하는 데이터가 없습니다."), # 빈 DataFrame 반환으로 처리
|
|
59
|
+
# 에러 코드
|
|
60
|
+
"ERROR_100": (EcosAPIError, "필수 값이 누락되어 있습니다."),
|
|
61
|
+
"ERROR_101": (EcosAPIError, "주기와 다른 형식의 날짜 형식입니다."),
|
|
62
|
+
"ERROR_200": (EcosAPIError, "파일타입 값이 누락 혹은 유효하지 않습니다."),
|
|
63
|
+
"ERROR_300": (EcosAPIError, "조회건수 값이 누락되어 있습니다."),
|
|
64
|
+
"ERROR_301": (EcosAPIError, "조회건수 값의 타입이 유효하지 않습니다."),
|
|
65
|
+
"ERROR_400": (EcosAPIError, "검색범위가 적정범위를 초과하여 TIMEOUT이 발생하였습니다."),
|
|
66
|
+
"ERROR_500": (EcosAPIError, "서버 오류입니다."), # 재시도 대상
|
|
67
|
+
"ERROR_600": (EcosAPIError, "DB Connection 오류입니다."), # 재시도 대상
|
|
68
|
+
"ERROR_601": (EcosAPIError, "SQL 오류입니다."),
|
|
69
|
+
"ERROR_602": (EcosRateLimitError, "과도한 OpenAPI 호출로 이용이 제한되었습니다."),
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# 재시도 가능한 에러 코드 (ECOS API는 하이픈 형식 사용: ERROR-500)
|
|
73
|
+
RETRYABLE_ERROR_CODES = {"ERROR-500", "ERROR-600", "ERROR-602"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ecos-reader 지표 모듈
|
|
3
|
+
|
|
4
|
+
각종 거시경제 지표 조회 함수를 제공합니다.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from .growth import get_gdp, get_gdp_deflator
|
|
10
|
+
from .interest_rate import get_base_rate, get_treasury_yield, get_yield_spread
|
|
11
|
+
from .money import get_bank_lending, get_money_supply
|
|
12
|
+
from .prices import get_core_cpi, get_cpi, get_ppi
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
# 금리 지표
|
|
16
|
+
"get_base_rate",
|
|
17
|
+
"get_treasury_yield",
|
|
18
|
+
"get_yield_spread",
|
|
19
|
+
# 물가 지표
|
|
20
|
+
"get_cpi",
|
|
21
|
+
"get_core_cpi",
|
|
22
|
+
"get_ppi",
|
|
23
|
+
# 성장 지표
|
|
24
|
+
"get_gdp",
|
|
25
|
+
"get_gdp_deflator",
|
|
26
|
+
# 통화 지표
|
|
27
|
+
"get_money_supply",
|
|
28
|
+
"get_bank_lending",
|
|
29
|
+
]
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""
|
|
2
|
+
성장 지표 모듈
|
|
3
|
+
|
|
4
|
+
GDP(국내총생산), GDP 디플레이터 등 성장 관련 지표를 조회합니다.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Literal
|
|
11
|
+
|
|
12
|
+
import pandas as pd
|
|
13
|
+
|
|
14
|
+
from ..client import get_client
|
|
15
|
+
from ..constants import (
|
|
16
|
+
ITEM_GDP,
|
|
17
|
+
ITEM_GDP_DEFLATOR,
|
|
18
|
+
PERIOD_ANNUAL,
|
|
19
|
+
PERIOD_QUARTERLY,
|
|
20
|
+
STAT_GDP_DEFLATOR,
|
|
21
|
+
STAT_GDP_NOMINAL,
|
|
22
|
+
STAT_GDP_REAL,
|
|
23
|
+
)
|
|
24
|
+
from ..parser import normalize_stat_result, parse_response
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _get_default_dates_quarterly(years_back: int = 5) -> tuple[str, str]:
|
|
28
|
+
"""기본 조회 기간을 반환합니다 (분기)."""
|
|
29
|
+
end_date = datetime.now()
|
|
30
|
+
start_year = end_date.year - years_back
|
|
31
|
+
current_quarter = (end_date.month - 1) // 3 + 1
|
|
32
|
+
|
|
33
|
+
start_str = f"{start_year}Q1"
|
|
34
|
+
end_str = f"{end_date.year}Q{current_quarter}"
|
|
35
|
+
|
|
36
|
+
return start_str, end_str
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _get_default_dates_annual(years_back: int = 10) -> tuple[str, str]:
|
|
40
|
+
"""기본 조회 기간을 반환합니다 (연간)."""
|
|
41
|
+
end_date = datetime.now()
|
|
42
|
+
start_year = end_date.year - years_back
|
|
43
|
+
|
|
44
|
+
return str(start_year), str(end_date.year)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def get_gdp(
|
|
48
|
+
frequency: Literal["Q", "A"] = "Q",
|
|
49
|
+
basis: Literal["real", "nominal"] = "real",
|
|
50
|
+
start_date: str | None = None,
|
|
51
|
+
end_date: str | None = None,
|
|
52
|
+
) -> pd.DataFrame:
|
|
53
|
+
"""
|
|
54
|
+
국내총생산(GDP)을 조회합니다.
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
frequency : str
|
|
59
|
+
조회 주기
|
|
60
|
+
- 'Q': 분기 (기본값)
|
|
61
|
+
- 'A': 연간
|
|
62
|
+
basis : str
|
|
63
|
+
GDP 기준
|
|
64
|
+
- 'real': 실질 GDP (기본값)
|
|
65
|
+
- 'nominal': 명목 GDP
|
|
66
|
+
start_date : str, optional
|
|
67
|
+
조회 시작일
|
|
68
|
+
- 분기: YYYYQN 형식 (예: 2020Q1)
|
|
69
|
+
- 연간: YYYY 형식 (예: 2020)
|
|
70
|
+
end_date : str, optional
|
|
71
|
+
조회 종료일
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
pd.DataFrame
|
|
76
|
+
컬럼: date, value, unit
|
|
77
|
+
- date: 날짜 (datetime)
|
|
78
|
+
- value: GDP (조원)
|
|
79
|
+
- unit: 단위
|
|
80
|
+
|
|
81
|
+
Notes
|
|
82
|
+
-----
|
|
83
|
+
- 실질 GDP: 물가 변동을 제외한 실제 생산량 변화
|
|
84
|
+
- 명목 GDP: 당해 연도 가격 기준 GDP
|
|
85
|
+
|
|
86
|
+
Examples
|
|
87
|
+
--------
|
|
88
|
+
>>> import ecos
|
|
89
|
+
>>> df = ecos.get_gdp() # 분기별 실질 GDP
|
|
90
|
+
>>> df.head()
|
|
91
|
+
|
|
92
|
+
>>> df = ecos.get_gdp(frequency="A", basis="nominal") # 연간 명목 GDP
|
|
93
|
+
"""
|
|
94
|
+
# 통계코드 선택
|
|
95
|
+
stat_code = STAT_GDP_REAL if basis == "real" else STAT_GDP_NOMINAL
|
|
96
|
+
|
|
97
|
+
# 주기 코드
|
|
98
|
+
period = PERIOD_QUARTERLY if frequency == "Q" else PERIOD_ANNUAL
|
|
99
|
+
|
|
100
|
+
# 기본 날짜 설정
|
|
101
|
+
if start_date is None or end_date is None:
|
|
102
|
+
if frequency == "Q":
|
|
103
|
+
default_start, default_end = _get_default_dates_quarterly(5)
|
|
104
|
+
else:
|
|
105
|
+
default_start, default_end = _get_default_dates_annual(10)
|
|
106
|
+
start_date = start_date or default_start
|
|
107
|
+
end_date = end_date or default_end
|
|
108
|
+
|
|
109
|
+
client = get_client()
|
|
110
|
+
response = client.get_statistic_search(
|
|
111
|
+
stat_code=stat_code,
|
|
112
|
+
period=period,
|
|
113
|
+
start_date=start_date,
|
|
114
|
+
end_date=end_date,
|
|
115
|
+
item_code1=ITEM_GDP,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
df = parse_response(response)
|
|
119
|
+
return normalize_stat_result(df)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def get_gdp_deflator(
|
|
123
|
+
frequency: Literal["Q", "A"] = "Q",
|
|
124
|
+
start_date: str | None = None,
|
|
125
|
+
end_date: str | None = None,
|
|
126
|
+
) -> pd.DataFrame:
|
|
127
|
+
"""
|
|
128
|
+
GDP 디플레이터를 조회합니다.
|
|
129
|
+
|
|
130
|
+
GDP 디플레이터는 명목 GDP와 실질 GDP의 비율로 계산되는
|
|
131
|
+
종합 물가지수입니다.
|
|
132
|
+
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
frequency : str
|
|
136
|
+
조회 주기
|
|
137
|
+
- 'Q': 분기 (기본값)
|
|
138
|
+
- 'A': 연간
|
|
139
|
+
start_date : str, optional
|
|
140
|
+
조회 시작일
|
|
141
|
+
end_date : str, optional
|
|
142
|
+
조회 종료일
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
pd.DataFrame
|
|
147
|
+
컬럼: date, value, unit
|
|
148
|
+
- date: 날짜 (datetime)
|
|
149
|
+
- value: GDP 디플레이터
|
|
150
|
+
- unit: 단위
|
|
151
|
+
|
|
152
|
+
Notes
|
|
153
|
+
-----
|
|
154
|
+
- GDP 디플레이터 = (명목 GDP / 실질 GDP) × 100
|
|
155
|
+
- CPI보다 포괄적인 물가 지표
|
|
156
|
+
- 국내에서 생산된 모든 재화와 서비스의 가격 변화 반영
|
|
157
|
+
|
|
158
|
+
Examples
|
|
159
|
+
--------
|
|
160
|
+
>>> import ecos
|
|
161
|
+
>>> df = ecos.get_gdp_deflator()
|
|
162
|
+
>>> df.head()
|
|
163
|
+
"""
|
|
164
|
+
# 주기 코드
|
|
165
|
+
period = PERIOD_QUARTERLY if frequency == "Q" else PERIOD_ANNUAL
|
|
166
|
+
|
|
167
|
+
# 기본 날짜 설정
|
|
168
|
+
if start_date is None or end_date is None:
|
|
169
|
+
if frequency == "Q":
|
|
170
|
+
default_start, default_end = _get_default_dates_quarterly(5)
|
|
171
|
+
else:
|
|
172
|
+
default_start, default_end = _get_default_dates_annual(10)
|
|
173
|
+
start_date = start_date or default_start
|
|
174
|
+
end_date = end_date or default_end
|
|
175
|
+
|
|
176
|
+
client = get_client()
|
|
177
|
+
response = client.get_statistic_search(
|
|
178
|
+
stat_code=STAT_GDP_DEFLATOR,
|
|
179
|
+
period=period,
|
|
180
|
+
start_date=start_date,
|
|
181
|
+
end_date=end_date,
|
|
182
|
+
item_code1=ITEM_GDP_DEFLATOR,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
df = parse_response(response)
|
|
186
|
+
return normalize_stat_result(df)
|