ecos-reader 0.2.0__tar.gz → 0.2.2__tar.gz
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_reader-0.2.2/.github/CODEOWNERS +2 -0
- ecos_reader-0.2.2/.github/dependabot.yml +32 -0
- ecos_reader-0.2.2/.github/workflows/codeql.yml +38 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/.github/workflows/docs.yml +9 -8
- ecos_reader-0.2.2/.github/workflows/nightly-e2e.yml +43 -0
- ecos_reader-0.2.2/.github/workflows/security.yml +39 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/.pre-commit-config.yaml +4 -1
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/CHANGELOG.md +46 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/PKG-INFO +11 -9
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/README.md +6 -6
- ecos_reader-0.2.2/docs/api-reference/client.md +9 -0
- ecos_reader-0.2.2/docs/api-reference/exceptions.md +35 -0
- ecos_reader-0.2.2/docs/api-reference/indicators.md +139 -0
- ecos_reader-0.2.2/docs/development/indicator-registry.md +28 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/examples/basic.md +4 -4
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/examples/dashboard.md +1 -1
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/getting-started/quickstart.md +4 -4
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/user-guide/advanced.md +1 -1
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/user-guide/basic-usage.md +3 -3
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/user-guide/fiscal.md +1 -1
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/user-guide/growth.md +28 -28
- ecos_reader-0.2.2/docs/user-guide/migration-frequency.md +84 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/user-guide/money.md +1 -1
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/mkdocs.yml +32 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/pyproject.toml +36 -4
- ecos_reader-0.2.2/scripts/gen_indicator_registry_doc.py +97 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/__init__.py +17 -1
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/cache.py +48 -41
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/client.py +85 -40
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/config.py +6 -0
- ecos_reader-0.2.2/src/ecos/exceptions.py +102 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/__init__.py +12 -37
- ecos_reader-0.2.2/src/ecos/indicators/_dates.py +64 -0
- ecos_reader-0.2.2/src/ecos/indicators/_frequency.py +106 -0
- ecos_reader-0.2.2/src/ecos/indicators/_registry.py +237 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/bond.py +5 -22
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/fiscal.py +6 -44
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/growth.py +93 -71
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/interest_rate.py +39 -32
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/money.py +16 -42
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/prices.py +15 -97
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/stock.py +11 -37
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/logging.py +4 -2
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/metrics.py +1 -1
- ecos_reader-0.2.2/tests/indicators/test_bond.py +68 -0
- ecos_reader-0.2.2/tests/indicators/test_dates.py +99 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/indicators/test_deprecations.py +3 -2
- ecos_reader-0.2.2/tests/indicators/test_fiscal.py +61 -0
- ecos_reader-0.2.2/tests/indicators/test_frequency.py +152 -0
- ecos_reader-0.2.2/tests/indicators/test_growth.py +422 -0
- ecos_reader-0.2.2/tests/indicators/test_interest_rate.py +335 -0
- ecos_reader-0.2.2/tests/indicators/test_money.py +644 -0
- ecos_reader-0.2.2/tests/indicators/test_prices.py +238 -0
- ecos_reader-0.2.2/tests/indicators/test_registry.py +193 -0
- ecos_reader-0.2.2/tests/indicators/test_stock.py +85 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/test_cache.py +46 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/test_client.py +96 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/test_e2e_indicators.py +45 -387
- ecos_reader-0.2.2/tests/test_exceptions.py +132 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/uv.lock +67 -3
- ecos_reader-0.2.0/docs/api-reference/client.md +0 -440
- ecos_reader-0.2.0/docs/api-reference/exceptions.md +0 -331
- ecos_reader-0.2.0/docs/api-reference/indicators.md +0 -432
- ecos_reader-0.2.0/src/ecos/exceptions.py +0 -73
- ecos_reader-0.2.0/tests/indicators/test_growth.py +0 -117
- ecos_reader-0.2.0/tests/indicators/test_interest_rate.py +0 -131
- ecos_reader-0.2.0/tests/indicators/test_money.py +0 -288
- ecos_reader-0.2.0/tests/indicators/test_prices.py +0 -98
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/.github/workflows/ci.yml +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/.github/workflows/publish.yml +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/.gitignore +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/API_SPEC.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/CONTRIBUTING.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/IMPLEMENTATION_STATUS.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/LICENSE +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/api-reference/overview.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/api-reference/statistic-item-list.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/api-reference/statistic-meta.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/api-reference/statistic-search.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/api-reference/statistic-table-list.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/api-reference/statistic-top-100.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/api-reference/statistic-word.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/development/contributing.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/development/release.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/getting-started/installation.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/index.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/user-guide/financial-markets.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/user-guide/interest-rates.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/docs/user-guide/prices.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/ecos_all_statistics.csv +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/ecos_implementation_status.csv +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/examples/basic_usage.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/examples/macro_dashboard.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/public-api-docs/statistic-item-list.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/public-api-docs/statistic-meta.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/public-api-docs/statistic-search.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/public-api-docs/statistic-table-list.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/public-api-docs/statistic-top-100.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/public-api-docs/statistic-word.md +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/constants.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/indicators/_deprecations.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/parser.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/py.typed +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/src/ecos/types.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/__init__.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/conftest.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/indicators/__init__.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/test_config.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/test_e2e.py +0 -0
- {ecos_reader-0.2.0 → ecos_reader-0.2.2}/tests/test_parser.py +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
# Python 의존성 (pyproject.toml / uv.lock) — 주간, 묶음 PR
|
|
4
|
+
- package-ecosystem: "pip"
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: "weekly"
|
|
8
|
+
day: "monday"
|
|
9
|
+
open-pull-requests-limit: 5
|
|
10
|
+
groups:
|
|
11
|
+
python-dependencies:
|
|
12
|
+
patterns:
|
|
13
|
+
- "*"
|
|
14
|
+
update-types:
|
|
15
|
+
- "minor"
|
|
16
|
+
- "patch"
|
|
17
|
+
commit-message:
|
|
18
|
+
prefix: "deps"
|
|
19
|
+
|
|
20
|
+
# GitHub Actions — 주간, 묶음 PR
|
|
21
|
+
- package-ecosystem: "github-actions"
|
|
22
|
+
directory: "/"
|
|
23
|
+
schedule:
|
|
24
|
+
interval: "weekly"
|
|
25
|
+
day: "monday"
|
|
26
|
+
open-pull-requests-limit: 5
|
|
27
|
+
groups:
|
|
28
|
+
github-actions:
|
|
29
|
+
patterns:
|
|
30
|
+
- "*"
|
|
31
|
+
commit-message:
|
|
32
|
+
prefix: "ci"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
# 매주 월요일 03:00 UTC — main에 머지된 코드의 정기 재스캔
|
|
10
|
+
- cron: "0 3 * * 1"
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: codeql-${{ github.ref }}
|
|
17
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
analyze:
|
|
21
|
+
name: Analyze (Python)
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
permissions:
|
|
24
|
+
security-events: write
|
|
25
|
+
contents: read
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Initialize CodeQL
|
|
30
|
+
uses: github/codeql-action/init@v3
|
|
31
|
+
with:
|
|
32
|
+
languages: python
|
|
33
|
+
queries: security-extended
|
|
34
|
+
|
|
35
|
+
- name: Perform CodeQL Analysis
|
|
36
|
+
uses: github/codeql-action/analyze@v3
|
|
37
|
+
with:
|
|
38
|
+
category: "/language:python"
|
|
@@ -17,17 +17,18 @@ jobs:
|
|
|
17
17
|
steps:
|
|
18
18
|
- uses: actions/checkout@v4
|
|
19
19
|
|
|
20
|
-
- name:
|
|
21
|
-
uses:
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v3
|
|
22
22
|
with:
|
|
23
|
-
|
|
23
|
+
enable-cache: true
|
|
24
24
|
|
|
25
|
-
- name:
|
|
26
|
-
run:
|
|
27
|
-
pip install mkdocs mkdocs-material
|
|
25
|
+
- name: Set up Python
|
|
26
|
+
run: uv python install 3.12
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
# docs extras(mkdocstrings 포함)로 빌드. --strict로 깨진 링크/누락을
|
|
29
|
+
# 빌드 실패로 검출 (#18). PR에서도 동일 검증이 실행된다.
|
|
30
|
+
- name: Build documentation (strict)
|
|
31
|
+
run: uv run --extra docs --python 3.12 mkdocs build --strict
|
|
31
32
|
|
|
32
33
|
- name: Deploy to GitHub Pages
|
|
33
34
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Nightly E2E
|
|
2
|
+
|
|
3
|
+
# 실 ECOS Open API를 호출하는 e2e 테스트를 매일 1회 실행해 외부 API 회귀를 감시한다.
|
|
4
|
+
# PR CI(ci.yml)는 `pytest -m "not e2e"`로 빠른 피드백만 담당하고, 실 API 검증은
|
|
5
|
+
# 여기서 분리 실행한다. (ECOS rate limit: 3분간 300회 / 초과 시 30분 차단)
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
schedule:
|
|
9
|
+
# 매일 18:00 UTC (= 03:00 KST)
|
|
10
|
+
- cron: "0 18 * * *"
|
|
11
|
+
workflow_dispatch: {}
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: ${{ github.workflow }}
|
|
18
|
+
cancel-in-progress: false
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
e2e:
|
|
22
|
+
name: E2E (real ECOS API)
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
# fork에는 secret이 없어 의미가 없으므로 upstream 레포에서만 실행
|
|
25
|
+
if: github.repository == 'choo121600/ecos-reader'
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Install uv
|
|
30
|
+
uses: astral-sh/setup-uv@v3
|
|
31
|
+
with:
|
|
32
|
+
enable-cache: true
|
|
33
|
+
|
|
34
|
+
- name: Set up Python
|
|
35
|
+
run: uv python install 3.12
|
|
36
|
+
|
|
37
|
+
- name: Sync dev dependencies
|
|
38
|
+
run: uv sync --extra dev --python 3.12
|
|
39
|
+
|
|
40
|
+
- name: Run e2e tests
|
|
41
|
+
env:
|
|
42
|
+
ECOS_API_KEY: ${{ secrets.ECOS_API_KEY }}
|
|
43
|
+
run: uv run pytest -m "e2e"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Security
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
# pip-audit는 신규 공시 취약점을 주기적으로 점검하는 용도(이슈 #19).
|
|
5
|
+
# PR 게이트는 CodeQL이 담당하므로 여기서는 주간 스케줄 + 수동 실행만 둔다.
|
|
6
|
+
schedule:
|
|
7
|
+
# 매주 월요일 04:00 UTC
|
|
8
|
+
- cron: "0 4 * * 1"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: security-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
pip-audit:
|
|
20
|
+
name: pip-audit
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@v3
|
|
27
|
+
with:
|
|
28
|
+
enable-cache: true
|
|
29
|
+
|
|
30
|
+
- name: Set up Python
|
|
31
|
+
run: uv python install 3.12
|
|
32
|
+
|
|
33
|
+
# 모든 extras를 포함해 .venv를 구성한 뒤, 설치된 환경을 직접 감사한다.
|
|
34
|
+
# requirements 파일 감사는 pip-audit가 격리 venv를 빌드하므로 환경 감사가 더 견고.
|
|
35
|
+
- name: Sync dependencies
|
|
36
|
+
run: uv sync --all-extras --python 3.12
|
|
37
|
+
|
|
38
|
+
- name: Run pip-audit
|
|
39
|
+
run: uv run --with pip-audit pip-audit
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
repos:
|
|
2
2
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
-
rev:
|
|
3
|
+
rev: v5.0.0
|
|
4
4
|
hooks:
|
|
5
5
|
- id: trailing-whitespace
|
|
6
6
|
- id: end-of-file-fixer
|
|
@@ -24,4 +24,7 @@ repos:
|
|
|
24
24
|
rev: v1.13.0
|
|
25
25
|
hooks:
|
|
26
26
|
- id: mypy
|
|
27
|
+
# mypy strict(#17)는 src 패키지에만 적용 — CI(ci.yml)의 `mypy src/ecos`와
|
|
28
|
+
# 동일 범위. 테스트는 무타입 함수가 정상이므로 strict 대상에서 제외.
|
|
29
|
+
files: ^src/ecos/
|
|
27
30
|
additional_dependencies: [types-requests]
|
|
@@ -5,6 +5,52 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.2] - 2026-05-30
|
|
9
|
+
|
|
10
|
+
> Epic #3(Extensibility & Long-term Design)의 하위 작업을 정리한 릴리스.
|
|
11
|
+
> 모든 변경이 하위호환이라, `0.3.0`(시그니처 breaking 재설계용 예약)을 침범하지
|
|
12
|
+
> 않도록 patch(0.2.2) 로 릴리스합니다.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- `frequency` 어휘를 풀네임으로 통일: `daily` / `monthly` / `quarterly` / `annual`.
|
|
16
|
+
카테고리마다 달랐던 표기(`growth` 의 `Q`/`A`, `interest_rate` 의 `D`/`M`,
|
|
17
|
+
`stock` 의 `daily`/`monthly`)를 정식 어휘로 일원화. PR #51 (#20).
|
|
18
|
+
- `EcosDeprecationWarning` 공개 export (`from ecos import EcosDeprecationWarning`).
|
|
19
|
+
레거시 입력값 사용 시 발생하며, 기본 경고 필터에서도 보이도록 `UserWarning` 기반.
|
|
20
|
+
- `mkdocstrings` 도입으로 indicator/클라이언트/예외 API 문서를 docstring 기반
|
|
21
|
+
자동 생성. PR #53 (#18).
|
|
22
|
+
|
|
23
|
+
### Deprecated
|
|
24
|
+
- 레거시 단일 문자 `frequency`(`"D"`/`"M"`/`"Q"`/`"A"`). 당분간 동작하되
|
|
25
|
+
`EcosDeprecationWarning` 을 발생시키며 **v0.4.0** 에서 제거 예정. 정식 어휘로
|
|
26
|
+
마이그레이션하세요(문서: 사용자 가이드 > frequency 마이그레이션). PR #51 (#20).
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- `mypy strict` 모드 적용 — `py.typed` 광고와 실제 타입 안전성을 일치. CI 의
|
|
30
|
+
`mypy src/ecos` 가 strict 를 강제. PR #52 (#17).
|
|
31
|
+
- `mkdocs build --strict` 적용 — 깨진 링크/누락 페이지를 빌드 실패로 검출,
|
|
32
|
+
PR 에서도 docs 빌드 검증. PR #53 (#18).
|
|
33
|
+
|
|
34
|
+
### Internal
|
|
35
|
+
- 보안/유지보수 자동화: `dependabot`(pip·github-actions), `CodeQL`(Python),
|
|
36
|
+
`pip-audit`(주간), `CODEOWNERS` 추가. `ruff` 규칙에 `S`(bandit)/`RUF`/`PT`/
|
|
37
|
+
`TC`/`N` 추가. PR #50 (#19).
|
|
38
|
+
|
|
39
|
+
## [0.2.1] - 2026-05-29
|
|
40
|
+
|
|
41
|
+
> 0.3.0 은 시그니처 breaking 재설계(epic #3)를 위해 예약돼 있어, 본 하위호환
|
|
42
|
+
> 기능 추가는 patch(0.2.1) 로 릴리스합니다.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- `get_base_rate` 에 `frequency` 파라미터 추가 (`"M"` 기본 / `"D"`). ECOS 통계표
|
|
46
|
+
`722Y001` 은 일별 원천이라 `frequency="D"` 로 변경일 단위(sparse) 시계열을
|
|
47
|
+
조회할 수 있습니다. `"D"` 지정 시 날짜 형식은 `YYYYMMDD`, 기본 조회기간도
|
|
48
|
+
일별 포맷으로 산출합니다. 기본값 `"M"` 으로 기존 동작은 그대로 유지(하위호환).
|
|
49
|
+
|
|
50
|
+
### Notes
|
|
51
|
+
- M2 평잔·계절조정(`161Y005`/`BBHS00`) 시계열은 기존
|
|
52
|
+
`get_m2_variants(variant="평잔_계절조정")` 로 이미 제공됩니다 (별도 추가 없음).
|
|
53
|
+
|
|
8
54
|
## [0.2.0] - 2026-05-29
|
|
9
55
|
|
|
10
56
|
v0.1.6 라이브 e2e 검증에서 드러난 follow-up(#2 Reliability epic)을 정리한 릴리스.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ecos-reader
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: 한국은행 ECOS Open API Python 클라이언트
|
|
5
5
|
Project-URL: Homepage, https://github.com/choo121600/ecos-reader
|
|
6
6
|
Project-URL: Documentation, https://choo121600.github.io/ecos-reader/
|
|
@@ -36,8 +36,10 @@ Requires-Dist: responses>=0.23.0; extra == 'dev'
|
|
|
36
36
|
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
37
37
|
Requires-Dist: types-requests>=2.28.0; extra == 'dev'
|
|
38
38
|
Provides-Extra: docs
|
|
39
|
-
Requires-Dist: mkdocs-material
|
|
40
|
-
Requires-Dist: mkdocs
|
|
39
|
+
Requires-Dist: mkdocs-material<10.0.0,>=9.5.0; extra == 'docs'
|
|
40
|
+
Requires-Dist: mkdocs<2.0.0,>=1.5.0; extra == 'docs'
|
|
41
|
+
Requires-Dist: mkdocstrings[python]>=0.24.0; extra == 'docs'
|
|
42
|
+
Requires-Dist: pymdown-extensions>=10.0; extra == 'docs'
|
|
41
43
|
Description-Content-Type: text/markdown
|
|
42
44
|
|
|
43
45
|
# ecos-reader
|
|
@@ -117,7 +119,7 @@ df = ecos.get_treasury_yield(maturity="10Y")
|
|
|
117
119
|
print(df)
|
|
118
120
|
|
|
119
121
|
# GDP 조회
|
|
120
|
-
df = ecos.get_gdp(frequency="
|
|
122
|
+
df = ecos.get_gdp(frequency="quarterly", basis="real")
|
|
121
123
|
print(df)
|
|
122
124
|
```
|
|
123
125
|
|
|
@@ -205,10 +207,10 @@ df = ecos.get_base_rate(start_date="202001", end_date="202312")
|
|
|
205
207
|
df = ecos.get_treasury_yield(maturity="3Y", start_date="20240101", end_date="20241231")
|
|
206
208
|
|
|
207
209
|
# 분기 데이터 (YYYYQN 형식)
|
|
208
|
-
df = ecos.get_gdp(frequency="
|
|
210
|
+
df = ecos.get_gdp(frequency="quarterly", start_date="2020Q1", end_date="2024Q4")
|
|
209
211
|
|
|
210
212
|
# 연간 데이터 (YYYY 형식)
|
|
211
|
-
df = ecos.get_gdp(frequency="
|
|
213
|
+
df = ecos.get_gdp(frequency="annual", start_date="2015", end_date="2024")
|
|
212
214
|
```
|
|
213
215
|
|
|
214
216
|
### 고급 사용 예제
|
|
@@ -238,14 +240,14 @@ plt.show()
|
|
|
238
240
|
import ecos
|
|
239
241
|
|
|
240
242
|
# 실질 GDP 및 성장률 조회
|
|
241
|
-
gdp = ecos.get_gdp(frequency="
|
|
242
|
-
growth = ecos.get_gdp_growth_rate(frequency="
|
|
243
|
+
gdp = ecos.get_gdp(frequency="quarterly", basis="real", start_date="2020Q1", end_date="2024Q4")
|
|
244
|
+
growth = ecos.get_gdp_growth_rate(frequency="quarterly", start_date="2020Q1", end_date="2024Q4")
|
|
243
245
|
|
|
244
246
|
# 산업별 기여도 분석
|
|
245
247
|
industry_gdp = ecos.get_gdp_by_industry(
|
|
246
248
|
basis="real",
|
|
247
249
|
seasonal_adj=True,
|
|
248
|
-
frequency="
|
|
250
|
+
frequency="quarterly",
|
|
249
251
|
start_date="2023Q1",
|
|
250
252
|
end_date="2023Q4"
|
|
251
253
|
)
|
|
@@ -75,7 +75,7 @@ df = ecos.get_treasury_yield(maturity="10Y")
|
|
|
75
75
|
print(df)
|
|
76
76
|
|
|
77
77
|
# GDP 조회
|
|
78
|
-
df = ecos.get_gdp(frequency="
|
|
78
|
+
df = ecos.get_gdp(frequency="quarterly", basis="real")
|
|
79
79
|
print(df)
|
|
80
80
|
```
|
|
81
81
|
|
|
@@ -163,10 +163,10 @@ df = ecos.get_base_rate(start_date="202001", end_date="202312")
|
|
|
163
163
|
df = ecos.get_treasury_yield(maturity="3Y", start_date="20240101", end_date="20241231")
|
|
164
164
|
|
|
165
165
|
# 분기 데이터 (YYYYQN 형식)
|
|
166
|
-
df = ecos.get_gdp(frequency="
|
|
166
|
+
df = ecos.get_gdp(frequency="quarterly", start_date="2020Q1", end_date="2024Q4")
|
|
167
167
|
|
|
168
168
|
# 연간 데이터 (YYYY 형식)
|
|
169
|
-
df = ecos.get_gdp(frequency="
|
|
169
|
+
df = ecos.get_gdp(frequency="annual", start_date="2015", end_date="2024")
|
|
170
170
|
```
|
|
171
171
|
|
|
172
172
|
### 고급 사용 예제
|
|
@@ -196,14 +196,14 @@ plt.show()
|
|
|
196
196
|
import ecos
|
|
197
197
|
|
|
198
198
|
# 실질 GDP 및 성장률 조회
|
|
199
|
-
gdp = ecos.get_gdp(frequency="
|
|
200
|
-
growth = ecos.get_gdp_growth_rate(frequency="
|
|
199
|
+
gdp = ecos.get_gdp(frequency="quarterly", basis="real", start_date="2020Q1", end_date="2024Q4")
|
|
200
|
+
growth = ecos.get_gdp_growth_rate(frequency="quarterly", start_date="2020Q1", end_date="2024Q4")
|
|
201
201
|
|
|
202
202
|
# 산업별 기여도 분석
|
|
203
203
|
industry_gdp = ecos.get_gdp_by_industry(
|
|
204
204
|
basis="real",
|
|
205
205
|
seasonal_adj=True,
|
|
206
|
-
frequency="
|
|
206
|
+
frequency="quarterly",
|
|
207
207
|
start_date="2023Q1",
|
|
208
208
|
end_date="2023Q4"
|
|
209
209
|
)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# 예외 처리
|
|
2
|
+
|
|
3
|
+
ecos-reader가 발생시키는 예외 및 경고 클래스의 자동 생성 API 레퍼런스입니다.
|
|
4
|
+
|
|
5
|
+
::: ecos.EcosError
|
|
6
|
+
options:
|
|
7
|
+
heading_level: 2
|
|
8
|
+
|
|
9
|
+
::: ecos.EcosAPIError
|
|
10
|
+
options:
|
|
11
|
+
heading_level: 2
|
|
12
|
+
|
|
13
|
+
::: ecos.EcosConfigError
|
|
14
|
+
options:
|
|
15
|
+
heading_level: 2
|
|
16
|
+
|
|
17
|
+
::: ecos.EcosNetworkError
|
|
18
|
+
options:
|
|
19
|
+
heading_level: 2
|
|
20
|
+
|
|
21
|
+
::: ecos.EcosRateLimitError
|
|
22
|
+
options:
|
|
23
|
+
heading_level: 2
|
|
24
|
+
|
|
25
|
+
::: ecos.EcosServerError
|
|
26
|
+
options:
|
|
27
|
+
heading_level: 2
|
|
28
|
+
|
|
29
|
+
::: ecos.EcosValidationError
|
|
30
|
+
options:
|
|
31
|
+
heading_level: 2
|
|
32
|
+
|
|
33
|
+
::: ecos.EcosPartialCoverageWarning
|
|
34
|
+
options:
|
|
35
|
+
heading_level: 2
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# 지표 함수
|
|
2
|
+
|
|
3
|
+
모든 지표 조회 함수의 자동 생성 API 레퍼런스입니다.
|
|
4
|
+
|
|
5
|
+
## 금리 지표
|
|
6
|
+
|
|
7
|
+
::: ecos.get_base_rate
|
|
8
|
+
options:
|
|
9
|
+
heading_level: 3
|
|
10
|
+
|
|
11
|
+
::: ecos.get_treasury_yield
|
|
12
|
+
options:
|
|
13
|
+
heading_level: 3
|
|
14
|
+
|
|
15
|
+
::: ecos.get_yield_spread
|
|
16
|
+
options:
|
|
17
|
+
heading_level: 3
|
|
18
|
+
|
|
19
|
+
::: ecos.get_bank_deposit_rate
|
|
20
|
+
options:
|
|
21
|
+
heading_level: 3
|
|
22
|
+
|
|
23
|
+
::: ecos.get_bank_lending_rate
|
|
24
|
+
options:
|
|
25
|
+
heading_level: 3
|
|
26
|
+
|
|
27
|
+
## 물가 지표
|
|
28
|
+
|
|
29
|
+
::: ecos.get_cpi
|
|
30
|
+
options:
|
|
31
|
+
heading_level: 3
|
|
32
|
+
|
|
33
|
+
::: ecos.get_core_cpi
|
|
34
|
+
options:
|
|
35
|
+
heading_level: 3
|
|
36
|
+
|
|
37
|
+
::: ecos.get_cpi_monthly
|
|
38
|
+
options:
|
|
39
|
+
heading_level: 3
|
|
40
|
+
|
|
41
|
+
::: ecos.get_cpi_by_category
|
|
42
|
+
options:
|
|
43
|
+
heading_level: 3
|
|
44
|
+
|
|
45
|
+
::: ecos.get_ppi
|
|
46
|
+
options:
|
|
47
|
+
heading_level: 3
|
|
48
|
+
|
|
49
|
+
## 성장 지표
|
|
50
|
+
|
|
51
|
+
::: ecos.get_gdp
|
|
52
|
+
options:
|
|
53
|
+
heading_level: 3
|
|
54
|
+
|
|
55
|
+
::: ecos.get_gdp_deflator
|
|
56
|
+
options:
|
|
57
|
+
heading_level: 3
|
|
58
|
+
|
|
59
|
+
::: ecos.get_gdp_growth_rate
|
|
60
|
+
options:
|
|
61
|
+
heading_level: 3
|
|
62
|
+
|
|
63
|
+
::: ecos.get_gdp_by_industry
|
|
64
|
+
options:
|
|
65
|
+
heading_level: 3
|
|
66
|
+
|
|
67
|
+
::: ecos.get_gdp_by_expenditure
|
|
68
|
+
options:
|
|
69
|
+
heading_level: 3
|
|
70
|
+
|
|
71
|
+
::: ecos.get_gdp_deflator_by_industry
|
|
72
|
+
options:
|
|
73
|
+
heading_level: 3
|
|
74
|
+
|
|
75
|
+
## 통화 지표
|
|
76
|
+
|
|
77
|
+
::: ecos.get_money_supply
|
|
78
|
+
options:
|
|
79
|
+
heading_level: 3
|
|
80
|
+
|
|
81
|
+
::: ecos.get_m1_variants
|
|
82
|
+
options:
|
|
83
|
+
heading_level: 3
|
|
84
|
+
|
|
85
|
+
::: ecos.get_m2_variants
|
|
86
|
+
options:
|
|
87
|
+
heading_level: 3
|
|
88
|
+
|
|
89
|
+
::: ecos.get_m2_by_holder
|
|
90
|
+
options:
|
|
91
|
+
heading_level: 3
|
|
92
|
+
|
|
93
|
+
::: ecos.get_bank_lending
|
|
94
|
+
options:
|
|
95
|
+
heading_level: 3
|
|
96
|
+
|
|
97
|
+
::: ecos.get_household_credit
|
|
98
|
+
options:
|
|
99
|
+
heading_level: 3
|
|
100
|
+
|
|
101
|
+
::: ecos.get_household_lending_detail
|
|
102
|
+
options:
|
|
103
|
+
heading_level: 3
|
|
104
|
+
|
|
105
|
+
::: ecos.get_borrower_loan
|
|
106
|
+
options:
|
|
107
|
+
heading_level: 3
|
|
108
|
+
|
|
109
|
+
## 채권 지표
|
|
110
|
+
|
|
111
|
+
::: ecos.get_bond_yield
|
|
112
|
+
options:
|
|
113
|
+
heading_level: 3
|
|
114
|
+
|
|
115
|
+
## 재정 지표
|
|
116
|
+
|
|
117
|
+
::: ecos.get_fiscal_balance
|
|
118
|
+
options:
|
|
119
|
+
heading_level: 3
|
|
120
|
+
|
|
121
|
+
## 주식시장 지표
|
|
122
|
+
|
|
123
|
+
::: ecos.get_stock_index
|
|
124
|
+
options:
|
|
125
|
+
heading_level: 3
|
|
126
|
+
|
|
127
|
+
::: ecos.get_investor_trading
|
|
128
|
+
options:
|
|
129
|
+
heading_level: 3
|
|
130
|
+
|
|
131
|
+
## 지표 레지스트리
|
|
132
|
+
|
|
133
|
+
::: ecos.list_indicators
|
|
134
|
+
options:
|
|
135
|
+
heading_level: 3
|
|
136
|
+
|
|
137
|
+
::: ecos.indicators.get_indicator
|
|
138
|
+
options:
|
|
139
|
+
heading_level: 3
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 선언적 지표 레지스트리 (Indicator Registry)
|
|
2
|
+
|
|
3
|
+
> 이 파일은 `scripts/gen_indicator_registry_doc.py` 가 `ecos.indicators.INDICATORS` 레지스트리에서 자동 생성합니다. 직접 편집하지 마세요.
|
|
4
|
+
>
|
|
5
|
+
> 전체 ECOS 통계 구현 현황은 `IMPLEMENTATION_STATUS.md` 를 참고하세요. 이 문서는 레지스트리에 등록된 단순 지표만 다룹니다.
|
|
6
|
+
|
|
7
|
+
등록된 선언적 지표: **6건**
|
|
8
|
+
|
|
9
|
+
## 금리
|
|
10
|
+
|
|
11
|
+
| name | 통계표코드 | 항목코드 | 주기 | 단위 | 설명 |
|
|
12
|
+
| --- | --- | --- | --- | --- | --- |
|
|
13
|
+
| `base_rate` | 722Y001 | 0101000 | 월별 | % | 한국은행 기준금리 |
|
|
14
|
+
|
|
15
|
+
## 물가
|
|
16
|
+
|
|
17
|
+
| name | 통계표코드 | 항목코드 | 주기 | 단위 | 설명 |
|
|
18
|
+
| --- | --- | --- | --- | --- | --- |
|
|
19
|
+
| `core_cpi` | 901Y010 | 00 | 월별 | % | 근원 소비자물가지수(Core CPI) |
|
|
20
|
+
| `cpi` | 901Y009 | 0 | 월별 | % | 소비자물가지수(CPI) 전년동월비 |
|
|
21
|
+
| `cpi_monthly` | 901Y009 | 0 | 월별 | - | 소비자물가지수 월별 원지수(총지수) |
|
|
22
|
+
| `ppi` | 404Y014 | *AA | 월별 | % | 생산자물가지수(PPI) |
|
|
23
|
+
|
|
24
|
+
## 재정
|
|
25
|
+
|
|
26
|
+
| name | 통계표코드 | 항목코드 | 주기 | 단위 | 설명 |
|
|
27
|
+
| --- | --- | --- | --- | --- | --- |
|
|
28
|
+
| `fiscal_balance` | 901Y013 | A | 월별 | 조원 | 통합재정수지 |
|
|
@@ -133,13 +133,13 @@ print("6. GDP")
|
|
|
133
133
|
print("=" * 60)
|
|
134
134
|
|
|
135
135
|
# 분기별 실질 GDP
|
|
136
|
-
df_gdp_q = ecos.get_gdp(frequency="
|
|
136
|
+
df_gdp_q = ecos.get_gdp(frequency="quarterly", basis="real")
|
|
137
137
|
print("분기별 실질 GDP:")
|
|
138
138
|
print(df_gdp_q.tail())
|
|
139
139
|
print()
|
|
140
140
|
|
|
141
141
|
# 연간 명목 GDP
|
|
142
|
-
df_gdp_a = ecos.get_gdp(frequency="
|
|
142
|
+
df_gdp_a = ecos.get_gdp(frequency="annual", basis="nominal")
|
|
143
143
|
print("연간 명목 GDP:")
|
|
144
144
|
print(df_gdp_a.tail())
|
|
145
145
|
print()
|
|
@@ -308,7 +308,7 @@ def fetch_all_indicators():
|
|
|
308
308
|
futures = {
|
|
309
309
|
'base_rate': executor.submit(ecos.get_base_rate),
|
|
310
310
|
'cpi': executor.submit(ecos.get_cpi),
|
|
311
|
-
'gdp': executor.submit(ecos.get_gdp, "
|
|
311
|
+
'gdp': executor.submit(ecos.get_gdp, "quarterly", "real"),
|
|
312
312
|
'm2': executor.submit(ecos.get_money_supply, "M2")
|
|
313
313
|
}
|
|
314
314
|
|
|
@@ -361,7 +361,7 @@ import pandas as pd
|
|
|
361
361
|
# 여러 지표 조회
|
|
362
362
|
base_rate = ecos.get_base_rate(start_date="202001")
|
|
363
363
|
cpi = ecos.get_cpi(start_date="202001")
|
|
364
|
-
gdp = ecos.get_gdp(frequency="
|
|
364
|
+
gdp = ecos.get_gdp(frequency="quarterly", start_date="2020Q1")
|
|
365
365
|
|
|
366
366
|
# Excel 저장 (여러 시트)
|
|
367
367
|
with pd.ExcelWriter('macro_indicators.xlsx', engine='openpyxl') as writer:
|
|
@@ -270,7 +270,7 @@ def plot_key_indicators():
|
|
|
270
270
|
ax2.grid(True, alpha=0.3)
|
|
271
271
|
|
|
272
272
|
# 3. GDP
|
|
273
|
-
df = ecos.get_gdp(frequency="
|
|
273
|
+
df = ecos.get_gdp(frequency="quarterly", start_date="2020Q1")
|
|
274
274
|
ax3.bar(range(len(df)), df['value'], color='green', alpha=0.7)
|
|
275
275
|
ax3.set_title('GDP 성장률 (분기)')
|
|
276
276
|
ax3.set_ylabel('%')
|
|
@@ -73,11 +73,11 @@ print(df.tail())
|
|
|
73
73
|
|
|
74
74
|
```python
|
|
75
75
|
# 분기별 실질 GDP
|
|
76
|
-
df = ecos.get_gdp(frequency="
|
|
76
|
+
df = ecos.get_gdp(frequency="quarterly", basis="real")
|
|
77
77
|
print(df.tail())
|
|
78
78
|
|
|
79
79
|
# 연간 명목 GDP
|
|
80
|
-
df = ecos.get_gdp(frequency="
|
|
80
|
+
df = ecos.get_gdp(frequency="annual", basis="nominal")
|
|
81
81
|
print(df.tail())
|
|
82
82
|
```
|
|
83
83
|
|
|
@@ -127,7 +127,7 @@ df = ecos.get_treasury_yield(
|
|
|
127
127
|
```python
|
|
128
128
|
# YYYYQN 형식
|
|
129
129
|
df = ecos.get_gdp(
|
|
130
|
-
frequency="
|
|
130
|
+
frequency="quarterly",
|
|
131
131
|
start_date="2020Q1",
|
|
132
132
|
end_date="2024Q4"
|
|
133
133
|
)
|
|
@@ -138,7 +138,7 @@ df = ecos.get_gdp(
|
|
|
138
138
|
```python
|
|
139
139
|
# YYYY 형식
|
|
140
140
|
df = ecos.get_gdp(
|
|
141
|
-
frequency="
|
|
141
|
+
frequency="annual",
|
|
142
142
|
start_date="2015",
|
|
143
143
|
end_date="2024"
|
|
144
144
|
)
|
|
@@ -406,7 +406,7 @@ with ThreadPoolExecutor(max_workers=4) as executor:
|
|
|
406
406
|
futures = {
|
|
407
407
|
'base_rate': executor.submit(ecos.get_base_rate),
|
|
408
408
|
'cpi': executor.submit(ecos.get_cpi),
|
|
409
|
-
'gdp': executor.submit(ecos.get_gdp, "
|
|
409
|
+
'gdp': executor.submit(ecos.get_gdp, "quarterly", "real"),
|
|
410
410
|
'm2': executor.submit(ecos.get_money_supply, "M2")
|
|
411
411
|
}
|
|
412
412
|
|