Metadata-Version: 2.3
Name: dart-enhanced
Version: 0.1.0
Summary: Async Python client for Korea's DART (FSS) OpenAPI with financial statement parsing
Project-URL: Homepage, https://github.com/dankang21/dart-enhanced
Project-URL: Documentation, https://github.com/dankang21/dart-enhanced#readme
Project-URL: Repository, https://github.com/dankang21/dart-enhanced
Project-URL: Issues, https://github.com/dankang21/dart-enhanced/issues
Author-email: Daniel Kang <dankang21@gmail.com>
License: MIT License
        
        Copyright (c) 2026 Daniel Kang
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: async,dart,disclosure,finance,financial-statements,fss,korea,korean-stock,opendart
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.9.0; extra == 'dev'
Description-Content-Type: text/markdown

# dart-enhanced

**Async Python client for Korea's DART (FSS) OpenAPI**

DART(전자공시시스템) OpenAPI를 위한 비동기 Python 클라이언트. 재무제표 파싱, 기업 개황, 공시 검색, 배당 조회를 지원합니다.

[![PyPI](https://img.shields.io/pypi/v/dart-enhanced)](https://pypi.org/project/dart-enhanced/)
[![Python](https://img.shields.io/pypi/pyversions/dart-enhanced)](https://pypi.org/project/dart-enhanced/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-20%20passed-brightgreen)]()

## Features

- **Async-first** — `httpx` 기반 비동기 HTTP 클라이언트
- **Zero pandas dependency** — 순수 Python dataclass, numpy 불필요
- **Financial statement parser** — 재무제표 원시 데이터를 구조화된 `ParsedFinancials`로 변환
- **Auto ratios** — ROE, ROA, 부채비율, 영업이익률, FCF 등 자동 계산
- **Fully typed** — `py.typed` 마커, 모든 공개 API에 타입 힌트
- **Corp code cache** — 기업 코드 매핑을 메모리 캐시하여 반복 조회 방지

## Installation

```bash
pip install dart-enhanced
```

## Quick Start

```python
import asyncio
from dart_enhanced import DartClient, DartApiError, parse_financial_statements, financials_to_dict

async def main():
    async with DartClient(api_key="YOUR_DART_API_KEY") as client:
        # 삼성전자 기업 개황
        info = await client.get_company_info_by_stock("005930")
        print(f"{info.corp_name} ({info.ceo})")
        # → 삼성전자 (한종희)

        # 재무제표 조회 + 파싱
        items = await client.get_financial_statements_by_stock(
            "005930", year=2024, report_type="annual"
        )
        parsed = parse_financial_statements(items)
        print(f"매출: {parsed.revenue:,}원")
        print(f"ROE: {parsed.roe:.2%}")
        print(f"부채비율: {parsed.debt_ratio:.2%}")

        # API 응답용 딕셔너리 변환
        data = financials_to_dict(parsed)
        print(data["ratios"])

asyncio.run(main())
```

### Error Handling

```python
from dart_enhanced import DartClient, DartApiError

async with DartClient() as client:
    try:
        info = await client.get_company_info_by_stock("999999")
    except ValueError as e:
        print(f"종목코드 없음: {e}")
    except DartApiError as e:
        print(f"DART API 오류: {e} (status={e.status_code})")
```

`DartApiError.status_code`에 DART API 오류 코드가 담깁니다:
- `"013"` — 조회된 데이터 없음
- `"020"` — 요청 제한 초과
- `"800"` — 시스템 점검 중

## API Reference

### DartClient

```python
client = DartClient(api_key="...")  # 또는 환경변수 DART_API_KEY
```

| Method | Description |
|--------|-------------|
| `load_corp_codes()` | 전체 기업 코드 매핑 로드 (종목코드 → corp_code) |
| `get_corp_code(stock_code)` | 종목코드(6자리)로 DART corp_code(8자리) 조회 |
| `get_company_info(corp_code)` | 기업 개황 조회 → `CompanyInfo` |
| `get_company_info_by_stock(stock_code)` | 종목코드로 기업 개황 조회 |
| `get_financial_statements(corp_code, year, report_type, consolidated)` | 재무제표 조회 → `list[FinancialItem]` |
| `get_financial_statements_by_stock(stock_code, ...)` | 종목코드로 재무제표 조회 |
| `search_disclosures(corp_code, begin_date, end_date, ...)` | 공시 검색 |
| `get_dividend_info(corp_code, year, report_type)` | 배당 정보 조회 |
| `close()` | HTTP 클라이언트 종료 (context manager 사용 시 자동 호출) |

> **종목코드 vs corp_code**: DART는 자체 기업코드(`corp_code`, 8자리)를 사용합니다. 증권거래소 종목코드(예: `005930`)와 다릅니다. `_by_stock` 메서드를 사용하면 종목코드 → corp_code 변환이 자동으로 처리됩니다.

### CompanyInfo

`get_company_info()` 반환 타입:

| Field | Type | Description |
|-------|------|-------------|
| `corp_code` | `str` | DART 기업 고유 코드 (8자리) |
| `corp_name` | `str` | 기업명 |
| `stock_code` | `str \| None` | 종목코드 (비상장 시 None) |
| `stock_name` | `str \| None` | 종목명 |
| `ceo` | `str` | 대표이사 |
| `corp_cls` | `str` | Y=유가, K=코스닥, N=코넥스, E=기타 |
| `address` | `str` | 본점 주소 |
| `website` | `str` | 홈페이지 URL |
| `industry_code` | `str` | 업종코드 |
| `established` | `str` | 설립일 (YYYYMMDD) |
| `fiscal_month` | `str` | 결산월 |

### FinancialItem

`get_financial_statements()` 반환 타입 (리스트):

| Field | Type | Description |
|-------|------|-------------|
| `account_id` | `str` | 계정 ID |
| `account_name` | `str` | 계정명 (예: "매출액", "자산총계") |
| `current_amount` | `int` | 당기 금액 |
| `previous_amount` | `int` | 전기 금액 |
| `before_previous_amount` | `int` | 전전기 금액 |
| `statement_type` | `str` | BS=재무상태표, IS=손익계산서, CF=현금흐름표, SCE=자본변동표 |

### Financial Statement Parser

```python
from dart_enhanced import parse_financial_statements, financials_to_dict, ParsedFinancials

parsed = parse_financial_statements(items)  # → ParsedFinancials
```

**재무상태표 (BS)**

| Property | Type | Description |
|----------|------|-------------|
| `total_assets` | `int` | 자산총계 |
| `total_liabilities` | `int` | 부채총계 |
| `total_equity` | `int` | 자본총계 |
| `current_assets` | `int` | 유동자산 |
| `current_liabilities` | `int` | 유동부채 |

**손익계산서 (IS)**

| Property | Type | Description |
|----------|------|-------------|
| `revenue` | `int` | 매출액 |
| `operating_income` | `int` | 영업이익 |
| `net_income` | `int` | 당기순이익 |

**현금흐름표 (CF)**

| Property | Type | Description |
|----------|------|-------------|
| `operating_cash_flow` | `int` | 영업활동현금흐름 |
| `investing_cash_flow` | `int` | 투자활동현금흐름 |
| `financing_cash_flow` | `int` | 재무활동현금흐름 |
| `fcf` | `int` | 잉여현금흐름 (영업CF + 투자CF, 자동 계산) |

**자동 계산 비율**

| Property | Type | Description |
|----------|------|-------------|
| `debt_ratio` | `float \| None` | 부채비율 (부채총계 / 자본총계) |
| `current_ratio` | `float \| None` | 유동비율 (유동자산 / 유동부채) |
| `operating_margin` | `float \| None` | 영업이익률 (영업이익 / 매출액) |
| `net_margin` | `float \| None` | 순이익률 (순이익 / 매출액) |
| `roe` | `float \| None` | 자기자본이익률 (순이익 / 자본총계) |
| `roa` | `float \| None` | 총자산이익률 (순이익 / 자산총계) |
| `revenue_growth` | `float \| None` | 매출 성장률 (전기 대비) |
| `net_income_growth` | `float \| None` | 순이익 성장률 (전기 대비) |

> 비율 속성은 분모가 0 이하일 때 `None`을 반환합니다.

```python
data = financials_to_dict(parsed)  # API 응답용 dict
# → {"balance_sheet": {...}, "income_statement": {...}, "cash_flow": {...}, "ratios": {...}, "growth": {...}}
```

### Report Types

| Key | Description |
|-----|-------------|
| `"annual"` | 사업보고서 |
| `"half"` | 반기보고서 |
| `"q1"` | 1분기보고서 |
| `"q3"` | 3분기보고서 |

### Consolidated vs Separate

`get_financial_statements()`의 `consolidated` 파라미터:

| Value | Description |
|-------|-------------|
| `True` (기본값) | 연결재무제표 (자회사 포함) |
| `False` | 별도재무제표 (해당 법인만) |

대부분의 분석에는 연결재무제표(`True`)를 사용합니다. 별도재무제표는 지주회사 분석 등 특수한 경우에 사용합니다.

## Important Notes

### 재무제표 파서 한계

- 파서는 DART 계정명 **한글 매칭**으로 동작합니다 (예: `"매출액"`, `"자산총계"`).
- 대부분의 상장기업에서 정상 동작하지만, 비표준 계정명을 사용하는 일부 기업에서 누락이 발생할 수 있습니다.
- 금융업(은행, 보험, 증권)은 재무제표 구조가 달라 파서가 일부 항목을 인식하지 못할 수 있습니다.

### 비동기 전용

이 라이브러리는 `async/await` 전용입니다. 동기 코드에서 사용하려면:

```python
import asyncio
result = asyncio.run(main())
```

## Environment Variables

| Variable | Description |
|----------|-------------|
| `DART_API_KEY` | DART OpenAPI 인증키 ([발급](https://opendart.fss.or.kr/)) |

## Comparison with Alternatives

| Feature | dart-enhanced | opendartreader | dart-fss |
|---------|:---:|:---:|:---:|
| Async | O | X | X |
| pandas-free | O | X | X |
| Type hints | O | Partial | Partial |
| Financial parser | O | X | O |
| Auto ratios (ROE, etc.) | O | X | X |
| Lightweight | O | X | X |

## DART API Key

1. [DART OpenAPI](https://opendart.fss.or.kr/) 접속
2. 회원가입 후 "인증키 신청"
3. 발급받은 키를 환경변수 `DART_API_KEY`로 설정하거나 `DartClient(api_key="...")`에 전달

## Disclaimer

이 라이브러리는 DART OpenAPI 데이터 조회를 위한 기술적 도구이며, 투자 권유 또는 금융 서비스를 제공하지 않습니다. 데이터 활용 시 [DART OpenAPI 이용약관](https://opendart.fss.or.kr/) 및 관련 법규를 준수할 책임은 사용자에게 있습니다.

This library is a technical tool for querying the DART OpenAPI and does not provide investment advice or financial services. Users are responsible for complying with the [DART OpenAPI Terms of Use](https://opendart.fss.or.kr/) and applicable laws.

## License

MIT License. See [LICENSE](LICENSE).
