krx-hj3415 2.2.1__tar.gz → 2.2.3__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.
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/PKG-INFO +1 -1
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/pyproject.toml +1 -1
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/cli.py +2 -1
- krx_hj3415-2.2.3/src/krx_hj3415/domain/universe.py +8 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/usecases/sync_universe.py +28 -42
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/LICENSE +0 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/README.md +0 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/__init__.py +0 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/domain/__init__.py +0 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/domain/diff.py +0 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/domain/types.py +0 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/provider/__init__.py +0 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/provider/krx300_samsungfund_excel.py +0 -0
- {krx_hj3415-2.2.1 → krx_hj3415-2.2.3}/src/krx_hj3415/usecases/__init__.py +0 -0
|
@@ -9,6 +9,7 @@ from db2_hj3415.settings import get_settings
|
|
|
9
9
|
from db2_hj3415.universe.repo import ensure_indexes as ensure_indexes_universe
|
|
10
10
|
from db2_hj3415.nfs.repo import ensure_indexes as ensure_indexes_nfs
|
|
11
11
|
|
|
12
|
+
from krx_hj3415.domain.universe import UniverseKind
|
|
12
13
|
from krx_hj3415.usecases.sync_universe import run_sync, apply_removed
|
|
13
14
|
|
|
14
15
|
app = typer.Typer(no_args_is_help=True)
|
|
@@ -58,7 +59,7 @@ def sync(
|
|
|
58
59
|
try:
|
|
59
60
|
await _mongo_bootstrap(db)
|
|
60
61
|
|
|
61
|
-
d = await run_sync(db, universe=universe, max_days=max_days, snapshot=snapshot)
|
|
62
|
+
d = await run_sync(db, universe=UniverseKind(universe), max_days=max_days, snapshot=snapshot)
|
|
62
63
|
|
|
63
64
|
typer.echo(f"\n=== UNIVERSE SYNC: {d.universe} ===")
|
|
64
65
|
typer.echo(f"asof: {d.asof.isoformat()}")
|
|
@@ -14,37 +14,20 @@ from db2_hj3415.universe.repo import (
|
|
|
14
14
|
)
|
|
15
15
|
from db2_hj3415.universe.repo import get_latest as get_universe_latest
|
|
16
16
|
|
|
17
|
-
from contracts_hj3415.universe.dto import UniverseItemDTO,
|
|
17
|
+
from contracts_hj3415.universe.dto import UniverseItemDTO, UniversePayloadDTO
|
|
18
|
+
from contracts_hj3415.universe.types import UniverseNames
|
|
18
19
|
|
|
19
20
|
from krx_hj3415.domain.types import CodeItem, UniverseDiff
|
|
20
21
|
from krx_hj3415.domain.diff import diff_universe
|
|
22
|
+
from krx_hj3415.domain.universe import UniverseKind
|
|
21
23
|
from krx_hj3415.provider.krx300_samsungfund_excel import fetch_krx300_items
|
|
22
24
|
|
|
23
25
|
|
|
24
|
-
def
|
|
25
|
-
|
|
26
|
-
db2 universe_latest 에 저장된 형태를 복원.
|
|
27
|
-
payload가 아래 중 뭐든 대응:
|
|
28
|
-
- {"items": [...]} 형태
|
|
29
|
-
- {"payload": {"items": [...]}} 형태
|
|
30
|
-
- 그냥 [...items...] 리스트
|
|
31
|
-
"""
|
|
32
|
-
if payload is None:
|
|
26
|
+
def _payload_dto_to_items(dto: UniversePayloadDTO) -> list[CodeItem]:
|
|
27
|
+
if dto is None:
|
|
33
28
|
return []
|
|
34
29
|
|
|
35
|
-
data =
|
|
36
|
-
if (
|
|
37
|
-
isinstance(data, dict)
|
|
38
|
-
and "payload" in data
|
|
39
|
-
and isinstance(data["payload"], dict)
|
|
40
|
-
):
|
|
41
|
-
data = data["payload"]
|
|
42
|
-
|
|
43
|
-
if isinstance(data, dict) and "items" in data:
|
|
44
|
-
data = data["items"]
|
|
45
|
-
|
|
46
|
-
if not isinstance(data, list):
|
|
47
|
-
return []
|
|
30
|
+
data = dto["items"]
|
|
48
31
|
|
|
49
32
|
out: list[CodeItem] = []
|
|
50
33
|
for row in data:
|
|
@@ -55,13 +38,7 @@ def _payload_to_items(payload: Any) -> list[CodeItem]:
|
|
|
55
38
|
continue
|
|
56
39
|
name = str(row.get("name") or "").strip()
|
|
57
40
|
market = row.get("market")
|
|
58
|
-
|
|
59
|
-
# asof는 DB에서 datetime으로 나오기도, ISO string으로 나오기도 함
|
|
60
|
-
if isinstance(asof_raw, datetime):
|
|
61
|
-
asof = asof_raw
|
|
62
|
-
else:
|
|
63
|
-
# fallback: 현재 시각 (정확도가 중요하면 ISO parse 추가)
|
|
64
|
-
asof = utcnow()
|
|
41
|
+
asof = utcnow()
|
|
65
42
|
out.append(CodeItem(code=code, name=name, asof=asof, market=market))
|
|
66
43
|
return out
|
|
67
44
|
|
|
@@ -71,7 +48,9 @@ async def refresh_krx300(*, max_days: int = 15) -> tuple[datetime, list[CodeItem
|
|
|
71
48
|
return fetch_krx300_items(max_days=max_days)
|
|
72
49
|
|
|
73
50
|
|
|
74
|
-
def to_universe_item_dtos(
|
|
51
|
+
def to_universe_item_dtos(
|
|
52
|
+
items: Iterable[Any], *, market: str = "KRX"
|
|
53
|
+
) -> list[UniverseItemDTO]:
|
|
75
54
|
out: list[UniverseItemDTO] = []
|
|
76
55
|
for it in items:
|
|
77
56
|
if it is None:
|
|
@@ -87,7 +66,7 @@ def to_universe_item_dtos(items: Iterable[Any], *, market: str = "KRX") -> list[
|
|
|
87
66
|
if not code:
|
|
88
67
|
continue
|
|
89
68
|
|
|
90
|
-
dto: UniverseItemDTO = {"code": code, "market":
|
|
69
|
+
dto: UniverseItemDTO = {"code": code, "market": market}
|
|
91
70
|
if isinstance(name, str) and name.strip():
|
|
92
71
|
dto["name"] = name.strip()
|
|
93
72
|
|
|
@@ -98,7 +77,7 @@ def to_universe_item_dtos(items: Iterable[Any], *, market: str = "KRX") -> list[
|
|
|
98
77
|
async def run_sync(
|
|
99
78
|
db: AsyncDatabase,
|
|
100
79
|
*,
|
|
101
|
-
universe:
|
|
80
|
+
universe: UniverseKind = UniverseKind.KRX300,
|
|
102
81
|
max_days: int = 15,
|
|
103
82
|
snapshot: bool = True,
|
|
104
83
|
) -> UniverseDiff:
|
|
@@ -109,27 +88,34 @@ async def run_sync(
|
|
|
109
88
|
4) latest upsert + (선택) snapshots insert
|
|
110
89
|
"""
|
|
111
90
|
# --- 1) fetch ---
|
|
112
|
-
if universe != "krx300":
|
|
113
|
-
raise ValueError(f"Unsupported universe: {universe}")
|
|
114
|
-
|
|
115
91
|
asof, new_items = await refresh_krx300(max_days=max_days)
|
|
116
92
|
|
|
117
93
|
# --- 2) load old ---
|
|
118
|
-
|
|
119
|
-
|
|
94
|
+
old_payload_dto = await get_universe_latest(
|
|
95
|
+
db, universe=cast(UniverseNames, universe.value)
|
|
96
|
+
)
|
|
97
|
+
old_items = _payload_dto_to_items(old_payload_dto)
|
|
120
98
|
|
|
121
99
|
# --- 3) diff ---
|
|
122
100
|
d = diff_universe(
|
|
123
|
-
universe=universe, asof=asof, new_items=new_items, old_items=old_items
|
|
101
|
+
universe=universe.value, asof=asof, new_items=new_items, old_items=old_items
|
|
124
102
|
)
|
|
125
103
|
|
|
126
104
|
# --- 4) save ---
|
|
127
105
|
await upsert_universe_latest(
|
|
128
|
-
db,
|
|
106
|
+
db,
|
|
107
|
+
universe=cast(UniverseNames, universe.value),
|
|
108
|
+
items=to_universe_item_dtos(new_items, market="KRX"),
|
|
109
|
+
asof=asof,
|
|
110
|
+
source="samsungfund",
|
|
129
111
|
)
|
|
130
112
|
if snapshot:
|
|
131
113
|
await insert_universe_snapshot(
|
|
132
|
-
db,
|
|
114
|
+
db,
|
|
115
|
+
universe=cast(UniverseNames, universe.value),
|
|
116
|
+
items=to_universe_item_dtos(new_items, market="KRX"),
|
|
117
|
+
asof=asof,
|
|
118
|
+
source="samsungfund",
|
|
133
119
|
)
|
|
134
120
|
|
|
135
121
|
return d
|
|
@@ -147,4 +133,4 @@ async def apply_removed(
|
|
|
147
133
|
if not codes:
|
|
148
134
|
return {"latest_deleted": 0, "snapshots_deleted": 0}
|
|
149
135
|
|
|
150
|
-
return await delete_codes_from_nfs(db, codes=codes, endpoint=None)
|
|
136
|
+
return await delete_codes_from_nfs(db, codes=codes, endpoint=None)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|