contracts-hj3415 0.1.0__tar.gz → 0.2.0__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.
Files changed (25) hide show
  1. {contracts_hj3415-0.1.0 → contracts_hj3415-0.2.0}/PKG-INFO +2 -8
  2. {contracts_hj3415-0.1.0 → contracts_hj3415-0.2.0}/pyproject.toml +5 -6
  3. contracts_hj3415-0.2.0/src/contracts/.DS_Store +0 -0
  4. contracts_hj3415-0.2.0/src/contracts/nfs/c101.py +52 -0
  5. contracts_hj3415-0.2.0/src/contracts/nfs/c103.py +19 -0
  6. contracts_hj3415-0.2.0/src/contracts/nfs/c104.py +24 -0
  7. contracts_hj3415-0.2.0/src/contracts/nfs/c106.py +37 -0
  8. contracts_hj3415-0.2.0/src/contracts/nfs/c108.py +61 -0
  9. contracts_hj3415-0.1.0/pytest.ini +0 -6
  10. contracts_hj3415-0.1.0/requirements.txt +0 -2
  11. contracts_hj3415-0.1.0/src/contracts_hj3415/common/base.py +0 -1
  12. contracts_hj3415-0.1.0/src/contracts_hj3415/common/types.py +0 -1
  13. contracts_hj3415-0.1.0/src/contracts_hj3415/common.py +0 -25
  14. contracts_hj3415-0.1.0/src/contracts_hj3415/events.py +0 -10
  15. contracts_hj3415-0.1.0/src/contracts_hj3415/items.py +0 -14
  16. contracts_hj3415-0.1.0/src/contracts_hj3415/nfs/__init__.py +0 -0
  17. contracts_hj3415-0.1.0/src/contracts_hj3415/nfs/delta.py +0 -0
  18. contracts_hj3415-0.1.0/src/contracts_hj3415/nfs/dim_account.py +0 -13
  19. contracts_hj3415-0.1.0/src/contracts_hj3415/nfs/dim_period.py +0 -0
  20. contracts_hj3415-0.1.0/src/contracts_hj3415/nfs/fact.py +0 -22
  21. contracts_hj3415-0.1.0/src/contracts_hj3415/users.py +0 -20
  22. {contracts_hj3415-0.1.0 → contracts_hj3415-0.2.0}/LICENSE +0 -0
  23. {contracts_hj3415-0.1.0 → contracts_hj3415-0.2.0}/README.md +0 -0
  24. {contracts_hj3415-0.1.0/src/contracts_hj3415 → contracts_hj3415-0.2.0/src/contracts}/__init__.py +0 -0
  25. {contracts_hj3415-0.1.0/src/contracts_hj3415/common → contracts_hj3415-0.2.0/src/contracts/nfs}/__init__.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: contracts-hj3415
3
- Version: 0.1.0
4
- Summary: A tiny example package
3
+ Version: 0.2.0
4
+ Summary: DTO pakages for hj3415
5
5
  Keywords: example,demo
6
6
  Author-email: Hyungjin Kim <hj3415@gmail.com>
7
7
  Requires-Python: >=3.11
@@ -11,11 +11,5 @@ Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Typing :: Typed
12
12
  License-File: LICENSE
13
13
  Requires-Dist: pydantic>=2.7
14
- Requires-Dist: contract-hj3415>=0.1
15
- Requires-Dist: pytest>=8 ; extra == "dev"
16
- Requires-Dist: pytest-cov>=7.0 ; extra == "dev"
17
- Requires-Dist: ruff>=0.5 ; extra == "dev"
18
- Requires-Dist: mypy>=1.10 ; extra == "dev"
19
- Provides-Extra: dev
20
14
 
21
15
 
@@ -4,8 +4,8 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "contracts-hj3415" # PyPI 이름 (하이픈 허용)
7
- version = "0.1.0"
8
- description = "A tiny example package"
7
+ version = "0.2.0"
8
+ description = "DTO pakages for hj3415"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
11
11
  license = { file = "LICENSE" }
@@ -19,9 +19,8 @@ classifiers = [
19
19
 
20
20
  dependencies = [
21
21
  "pydantic>=2.7",
22
- "contract-hj3415>=0.1",
23
22
  ]
24
23
 
25
- # 선택적 의존성 (pip install your-pkg[dev] 형태)
26
- [project.optional-dependencies]
27
- dev = ["pytest>=8", "pytest-cov>=7.0", "ruff>=0.5", "mypy>=1.10"]
24
+ [tool.flit.module]
25
+ name = "contracts"
26
+ path = "src/contracts"
@@ -0,0 +1,52 @@
1
+ # contracts/nfs/c101.py
2
+ from __future__ import annotations
3
+
4
+ from pydantic import BaseModel, Field
5
+ from typing import Optional
6
+
7
+
8
+ class C101DTO(BaseModel):
9
+ # 기본 식별 정보
10
+ 종목명: str
11
+ 코드: str
12
+ 날짜: str
13
+ 업종: str
14
+
15
+ # 재무 지표
16
+ eps: Optional[int] = None
17
+ bps: Optional[int] = None
18
+ per: Optional[float] = None
19
+ 업종per: Optional[float] = None
20
+ pbr: Optional[float] = None
21
+ 배당수익률: Optional[float] = None
22
+
23
+ # 주가 정보
24
+ 주가: Optional[int] = None
25
+ 전일대비: Optional[int] = None
26
+ 수익률: Optional[float] = None
27
+
28
+ 최고52: Optional[int] = None
29
+ 최저52: Optional[int] = None
30
+
31
+ 거래량: Optional[int] = None
32
+ 거래대금: Optional[int] = None
33
+ 시가총액: Optional[int] = None
34
+
35
+ 베타52주: Optional[float] = None
36
+
37
+ 발행주식: Optional[int] = None
38
+ 유동비율: Optional[float] = None
39
+ 외국인지분율: Optional[float] = None
40
+
41
+ # 기간 수익률
42
+ 수익률1M: Optional[float] = None
43
+ 수익률3M: Optional[float] = None
44
+ 수익률6M: Optional[float] = None
45
+ 수익률1Y: Optional[float] = None
46
+
47
+ # 텍스트 정보
48
+ 개요: str = ""
49
+
50
+ class Config:
51
+ # 한글 필드명을 그대로 쓰기 위한 옵션
52
+ populate_by_name = True
@@ -0,0 +1,19 @@
1
+ # contracts/nfs/c103.py
2
+ from __future__ import annotations
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field
5
+
6
+ Num = float | int | None
7
+ Row = dict[str, Num] # 예: {"2020/12": 1.0, "전년대비": 2.0, ...}
8
+ ItemsMap = dict[str, Row] # 예: {"매출액(수익)": {...}, ...}
9
+
10
+ class C103DTO(BaseModel):
11
+ 코드: str
12
+ 손익계산서y: ItemsMap = Field(default_factory=dict)
13
+ 손익계산서q: ItemsMap = Field(default_factory=dict)
14
+ 재무상태표y: ItemsMap = Field(default_factory=dict)
15
+ 재무상태표q: ItemsMap = Field(default_factory=dict)
16
+ 현금흐름표y: ItemsMap = Field(default_factory=dict)
17
+ 현금흐름표q: ItemsMap = Field(default_factory=dict)
18
+
19
+ model_config = ConfigDict(extra="ignore")
@@ -0,0 +1,24 @@
1
+ # contracts/nfs/c104.py
2
+ from __future__ import annotations
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field
5
+
6
+ Num = float | int | None
7
+ Row = dict[str, Num] # 예: {"2020/12": 1.0, "전년대비": 2.0, ...}
8
+ ItemsMap = dict[str, Row] # 예: {"ROE": {...}, ...}
9
+
10
+ class C104DTO(BaseModel):
11
+ 코드: str
12
+ 수익성y: ItemsMap = Field(default_factory=dict)
13
+ 수익성q: ItemsMap = Field(default_factory=dict)
14
+ 성장성y: ItemsMap = Field(default_factory=dict)
15
+ 성장성q: ItemsMap = Field(default_factory=dict)
16
+ 안정성y: ItemsMap = Field(default_factory=dict)
17
+ 안정성q: ItemsMap = Field(default_factory=dict)
18
+ 활동성y: ItemsMap = Field(default_factory=dict)
19
+ 활동성q: ItemsMap = Field(default_factory=dict)
20
+ 가치분석y: ItemsMap = Field(default_factory=dict)
21
+ 가치분석q: ItemsMap = Field(default_factory=dict)
22
+
23
+
24
+ model_config = ConfigDict(extra="ignore")
@@ -0,0 +1,37 @@
1
+ # contracts/nfs/c106.py
2
+ from __future__ import annotations
3
+
4
+ from pydantic import BaseModel, Field, ConfigDict
5
+
6
+ NumMap = dict[str, float | None]
7
+
8
+
9
+ class C106Block(BaseModel):
10
+ 전일종가: NumMap = Field(default_factory=dict)
11
+ 시가총액: NumMap = Field(default_factory=dict)
12
+ 자산총계: NumMap = Field(default_factory=dict)
13
+ 부채총계: NumMap = Field(default_factory=dict)
14
+
15
+ 매출액: NumMap = Field(default_factory=dict)
16
+ 영업이익: NumMap = Field(default_factory=dict)
17
+ 당기순이익: NumMap = Field(default_factory=dict)
18
+ 당기순이익_지배: NumMap = Field(default_factory=dict)
19
+
20
+ 영업이익률: NumMap = Field(default_factory=dict)
21
+ 순이익률: NumMap = Field(default_factory=dict)
22
+ ROE: NumMap = Field(default_factory=dict)
23
+ 부채비율: NumMap = Field(default_factory=dict)
24
+
25
+ PER: NumMap = Field(default_factory=dict)
26
+ PBR: NumMap = Field(default_factory=dict)
27
+
28
+ 투자의견: NumMap = Field(default_factory=dict)
29
+ 목표주가: NumMap = Field(default_factory=dict)
30
+
31
+ model_config = ConfigDict(extra="ignore")
32
+
33
+
34
+ class C106DTO(BaseModel):
35
+ 코드: str
36
+ q: C106Block
37
+ y: C106Block
@@ -0,0 +1,61 @@
1
+ import math
2
+ from pydantic import BaseModel, field_validator
3
+ from typing import List, Optional, Any
4
+ import re
5
+
6
+ class C108DTO(BaseModel):
7
+ 코드: str
8
+ 날짜: Optional[str]
9
+ 제목: str
10
+ 작성자: Optional[str]
11
+ 제공처: Optional[str]
12
+ 투자의견: Optional[str]
13
+ 목표가: Optional[float]
14
+ 분량: Optional[str]
15
+ 내용: List[str]
16
+
17
+
18
+ @field_validator("투자의견", mode="before")
19
+ @classmethod
20
+ def _coerce_opinion(cls, v):
21
+ # pandas/bs4 parsing sometimes yields float('nan') for empty cells
22
+ if v is None:
23
+ return None
24
+ if isinstance(v, float) and math.isnan(v):
25
+ return None
26
+ if isinstance(v, str):
27
+ s = v.strip()
28
+ if not s or s.lower() == "nan" or s in {"-", "N/A", "NA"}:
29
+ return None
30
+ return s
31
+ # Any other type -> string fallback (keeps validation tolerant)
32
+ return str(v)
33
+
34
+ @field_validator("목표가", mode="before")
35
+ @classmethod
36
+ def _v_target_price(cls, v: Any):
37
+ if v is None:
38
+ return None
39
+
40
+ # nan 방어
41
+ if isinstance(v, float) and math.isnan(v):
42
+ return None
43
+
44
+ # 안내 문구/결측 문자열 방어
45
+ if isinstance(v, str):
46
+ s = v.strip()
47
+ if not s or s in {"-", "N/A"} or "검색된 데이터가 없습니다" in s:
48
+ return None
49
+
50
+ # "123,456원" 같은 케이스에서 숫자만 추출
51
+ m = re.findall(r"\d+(?:,\d+)*", s)
52
+ if not m:
53
+ return None
54
+ return float(m[0].replace(",", ""))
55
+
56
+ # 숫자면 그대로 float로
57
+ if isinstance(v, (int, float)):
58
+ return float(v)
59
+
60
+ # 그 외 타입은 None 처리(또는 raise로 엄격하게)
61
+ return None
@@ -1,6 +0,0 @@
1
- #pytest.ini
2
- [pytest]
3
- addopts = -q -s --cov=contract_hj3415 --cov-report=term-missing
4
- testpaths = tests
5
- python_files = test_*.py *_test.py
6
- filterwarnings = ignore::DeprecationWarning
@@ -1,2 +0,0 @@
1
- pydantic>=2.7
2
- contract-hj3415>=0.1
@@ -1 +0,0 @@
1
- # Base DTO, mixins, timestamp helpers
@@ -1 +0,0 @@
1
- # Literal, Enum 정의 등
@@ -1,25 +0,0 @@
1
- #src/contracts_hj3415/common.py — 공용 타입, 베이스 모델, Enum 등
2
-
3
- from datetime import datetime
4
- from uuid import UUID, uuid4
5
- from enum import Enum
6
- from pydantic import BaseModel, Field
7
-
8
- class IDModel(BaseModel):
9
- id: UUID = Field(default_factory=uuid4)
10
-
11
- class TimestampMixin(BaseModel):
12
- created_at: datetime = Field(default_factory=datetime.utcnow)
13
- updated_at: datetime | None = None
14
-
15
- class UserRole(str, Enum):
16
- ADMIN = "admin"
17
- STAFF = "staff"
18
- CUSTOMER = "customer"
19
-
20
- # 공통 BaseModel
21
- class ContractModel(BaseModel):
22
- class Config:
23
- orm_mode = True
24
- extra = "forbid"
25
- from_attributes = True
@@ -1,10 +0,0 @@
1
- # src/contracts_hj3415/events.py — 메시지 / 이벤트 스키마
2
-
3
- from datetime import datetime
4
- from uuid import UUID
5
- from pydantic import BaseModel
6
-
7
- class UserCreatedEvent(BaseModel):
8
- event: str = "user.created"
9
- user_id: UUID
10
- timestamp: datetime
@@ -1,14 +0,0 @@
1
- #src/contracts_hj3415/items.py — 아이템 관련 DTO
2
-
3
- from datetime import datetime
4
- from .common import IDModel, ContractModel
5
-
6
- class ItemBase(ContractModel):
7
- name: str
8
- description: str | None = None
9
-
10
- class ItemCreate(ItemBase):
11
- pass
12
-
13
- class ItemRead(IDModel, ItemBase):
14
- created_at: datetime
File without changes
@@ -1,13 +0,0 @@
1
- # contracts_hj3415/nfs/dim_account.py
2
- from pydantic import BaseModel
3
- from typing import Optional
4
-
5
- class DimAccountDTO(BaseModel):
6
- accode: str
7
- account_name: str
8
- level: Optional[int] = None
9
- parent_accode: Optional[str] = None
10
- group_type: Optional[int] = None
11
- unit_type: Optional[int] = None
12
- acc_kind: Optional[str] = None
13
- precision: Optional[int] = None
@@ -1,22 +0,0 @@
1
- # contracts_hj3415/nfs/fact.py
2
- from pydantic import BaseModel, Field
3
- from datetime import date
4
- from typing import Optional
5
-
6
- class FactFinanceDTO(BaseModel):
7
- cmp_cd: str
8
- page: str
9
- rpt: str
10
- frq: str
11
- accode: str
12
- account_name: str
13
- period: date
14
- value: float
15
- basis: Optional[str] = None
16
- is_estimate: bool = False
17
- unit_type: Optional[int] = None
18
- level: Optional[int] = None
19
- parent_accode: Optional[str] = None
20
- group_type: Optional[int] = None
21
- acc_kind: Optional[str] = None
22
- precision: Optional[int] = None
@@ -1,20 +0,0 @@
1
- #src/contracts_hj3415/users.py — 사용자 관련 DTO
2
-
3
- from datetime import datetime
4
- from pydantic import BaseModel, EmailStr
5
- from .common import IDModel, ContractModel, UserRole
6
-
7
- class UserBase(ContractModel):
8
- email: EmailStr
9
- nickname: str | None = None
10
- role: UserRole = UserRole.CUSTOMER
11
-
12
- class UserCreate(UserBase):
13
- password: str
14
-
15
- class UserUpdate(BaseModel):
16
- nickname: str | None = None
17
- role: UserRole | None = None
18
-
19
- class UserRead(IDModel, UserBase):
20
- created_at: datetime