krx-hj3415 2.2.1__py3-none-any.whl → 2.2.3__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.
krx_hj3415/cli.py CHANGED
@@ -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()}")
@@ -0,0 +1,8 @@
1
+ # krx300_hj3415/domain/universe.py
2
+ from __future__ import annotations
3
+
4
+ from enum import StrEnum
5
+
6
+ class UniverseKind(StrEnum):
7
+ KRX300 = "krx300"
8
+
@@ -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, Market
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 _payload_to_items(payload: Any) -> list[CodeItem]:
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 = payload
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
- asof_raw = row.get("asof")
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(items: Iterable[Any], *, market: str = "KRX") -> list[UniverseItemDTO]:
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": cast(Market, 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: str = "krx300",
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
- old_doc = await get_universe_latest(db, universe=universe)
119
- old_items = _payload_to_items(old_doc)
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, universe=universe, items=to_universe_item_dtos(new_items), asof=asof
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, universe=universe, items=to_universe_item_dtos(new_items), asof=asof
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: krx-hj3415
3
- Version: 2.2.1
3
+ Version: 2.2.3
4
4
  Summary: KRX300 code scraper
5
5
  Keywords: example,demo
6
6
  Author-email: Hyungjin Kim <hj3415@gmail.com>
@@ -1,14 +1,15 @@
1
1
  krx_hj3415/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- krx_hj3415/cli.py,sha256=F6ZpX8k1fNwtsRv59ixv3d1dPSnmWyxwXZbzu61ViWI,3174
2
+ krx_hj3415/cli.py,sha256=i4KbK1j_gOpITNCDuBJR2aY8LU45J5WBRcMbacDavt8,3240
3
3
  krx_hj3415/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  krx_hj3415/domain/diff.py,sha256=m6nl73Anjx2si6vr9a-FXdH5iKVHh_4kXF9RHgplSdY,847
5
5
  krx_hj3415/domain/types.py,sha256=-ERCYZXLX0LGjqEthcrBUpNWgBf2tJ5NgHE5Zxg2pls,663
6
+ krx_hj3415/domain/universe.py,sha256=eL1huxToFudvqmYKiDHmkpTvunz5VDXjTpuWoQ6mA00,149
6
7
  krx_hj3415/provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
8
  krx_hj3415/provider/krx300_samsungfund_excel.py,sha256=WCQAeBsED5Cp9-4lZcptifwX1yY_-XRAP4iO8w5kb0A,2776
8
9
  krx_hj3415/usecases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- krx_hj3415/usecases/sync_universe.py,sha256=jlhMdKJsFbBD87kX0Y4eiuQdxVDWcpv07OJ45_bMFlg,4489
10
- krx_hj3415-2.2.1.dist-info/entry_points.txt,sha256=qasj01Y1e0MIVlUXOraAZCAxDTn07CyMVV58hrYDamA,42
11
- krx_hj3415-2.2.1.dist-info/licenses/LICENSE,sha256=QBiVGQuKAESeCfQE344Ik2ex6g2zfYdu9WqrRWydxIs,1068
12
- krx_hj3415-2.2.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
13
- krx_hj3415-2.2.1.dist-info/METADATA,sha256=Ke-YK_6EX_bQ8gjWIuq4tYwijSmejkyjaTCg5xStq6E,2290
14
- krx_hj3415-2.2.1.dist-info/RECORD,,
10
+ krx_hj3415/usecases/sync_universe.py,sha256=xhas9NBQW5v4KM--Df3hxhuOrlM4GpoqDP4HRw-Fnu4,4008
11
+ krx_hj3415-2.2.3.dist-info/entry_points.txt,sha256=qasj01Y1e0MIVlUXOraAZCAxDTn07CyMVV58hrYDamA,42
12
+ krx_hj3415-2.2.3.dist-info/licenses/LICENSE,sha256=QBiVGQuKAESeCfQE344Ik2ex6g2zfYdu9WqrRWydxIs,1068
13
+ krx_hj3415-2.2.3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
14
+ krx_hj3415-2.2.3.dist-info/METADATA,sha256=o0KpFVVjZBipIWR4su8sJBXvPEirQUwylmEyG0ay5q4,2290
15
+ krx_hj3415-2.2.3.dist-info/RECORD,,