kabukit 0.2.0__py3-none-any.whl → 0.3.0__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.
kabukit/cli/app.py CHANGED
@@ -5,13 +5,14 @@ from __future__ import annotations
5
5
  import typer
6
6
  from async_typer import AsyncTyper # pyright: ignore[reportMissingTypeStubs]
7
7
 
8
- from . import auth
8
+ from . import auth, get
9
9
 
10
10
  app = AsyncTyper(
11
11
  add_completion=False,
12
12
  help="J-Quants/EDINETデータツール",
13
13
  )
14
14
  app.add_typer(auth.app, name="auth")
15
+ app.add_typer(get.app, name="get")
15
16
 
16
17
 
17
18
  @app.command()
kabukit/cli/get.py ADDED
@@ -0,0 +1,104 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Annotated, Any
4
+
5
+ import typer
6
+ from async_typer import AsyncTyper # pyright: ignore[reportMissingTypeStubs]
7
+ from typer import Argument
8
+
9
+ app = AsyncTyper(
10
+ add_completion=False,
11
+ help="J-Quantsからデータを取得します。",
12
+ )
13
+
14
+ Code = Annotated[
15
+ str | None,
16
+ Argument(help="銘柄コード。指定しない場合は全銘柄の情報を取得します。"),
17
+ ]
18
+
19
+
20
+ @app.async_command() # pyright: ignore[reportUnknownMemberType]
21
+ async def info(code: Code = None) -> None:
22
+ """上場銘柄一覧を取得します。"""
23
+ from kabukit.core.info import Info
24
+ from kabukit.jquants.client import JQuantsClient
25
+
26
+ async with JQuantsClient() as client:
27
+ df = await client.get_info(code)
28
+
29
+ typer.echo(df)
30
+
31
+ if code is None:
32
+ path = Info(df).write()
33
+ typer.echo(f"全銘柄の情報を '{path}' に保存しました。")
34
+
35
+
36
+ async def _fetch(
37
+ code: str | None,
38
+ target: str,
39
+ writer_cls: type,
40
+ fetch_func_name: str,
41
+ message: str,
42
+ **kwargs: Any,
43
+ ) -> None:
44
+ """財務情報・株価情報を取得するための共通処理"""
45
+ from kabukit.jquants.client import JQuantsClient
46
+
47
+ if code is not None:
48
+ async with JQuantsClient() as client:
49
+ df = await getattr(client, fetch_func_name)(code)
50
+ typer.echo(df)
51
+ return
52
+
53
+ import tqdm.asyncio
54
+
55
+ from kabukit.jquants.concurrent import fetch_all
56
+
57
+ df = await fetch_all(target, progress=tqdm.asyncio.tqdm, **kwargs)
58
+ typer.echo(df)
59
+ path = writer_cls(df).write()
60
+ typer.echo(f"全銘柄の{message}を '{path}' に保存しました。")
61
+
62
+
63
+ @app.async_command() # pyright: ignore[reportUnknownMemberType]
64
+ async def statements(code: Code = None) -> None:
65
+ """財務情報を取得します。"""
66
+ from kabukit.core.statements import Statements
67
+
68
+ await _fetch(
69
+ code=code,
70
+ target="statements",
71
+ writer_cls=Statements,
72
+ fetch_func_name="get_statements",
73
+ message="財務情報",
74
+ )
75
+
76
+
77
+ @app.async_command() # pyright: ignore[reportUnknownMemberType]
78
+ async def prices(code: Code = None) -> None:
79
+ """株価を取得します。"""
80
+ from kabukit.core.prices import Prices
81
+
82
+ await _fetch(
83
+ code=code,
84
+ target="prices",
85
+ writer_cls=Prices,
86
+ fetch_func_name="get_prices",
87
+ message="株価情報",
88
+ max_concurrency=8,
89
+ )
90
+
91
+
92
+ @app.async_command(name="all") # pyright: ignore[reportUnknownMemberType]
93
+ async def all_(code: Code = None) -> None:
94
+ """上場銘柄一覧、財務情報、株価を連続して取得します。"""
95
+ typer.echo("上場銘柄一覧を取得します。")
96
+ await info(code)
97
+
98
+ typer.echo("---")
99
+ typer.echo("財務情報を取得します。")
100
+ await statements(code)
101
+
102
+ typer.echo("---")
103
+ typer.echo("株価を取得します。")
104
+ await prices(code)
kabukit/core/base.py CHANGED
@@ -36,10 +36,15 @@ class Base:
36
36
  def read(cls, path: str | None = None) -> Self:
37
37
  data_dir = cls.data_dir()
38
38
 
39
- if path is None:
40
- filename = sorted(data_dir.glob("*.parquet"))[-1]
41
- else:
39
+ if path:
42
40
  filename = data_dir / path
41
+ else:
42
+ filenames = sorted(data_dir.glob("*.parquet"))
43
+ if not filenames:
44
+ msg = f"No data found in {data_dir}"
45
+ raise FileNotFoundError(msg)
46
+
47
+ filename = filenames[-1]
43
48
 
44
49
  data = pl.read_parquet(filename)
45
50
  return cls(data)
@@ -1,13 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- import datetime
4
3
  from typing import TYPE_CHECKING
5
4
 
6
5
  from kabukit.utils import concurrent
6
+ from kabukit.utils.date import get_dates
7
7
 
8
8
  from .client import EdinetClient
9
9
 
10
10
  if TYPE_CHECKING:
11
+ import datetime
11
12
  from collections.abc import Iterable
12
13
 
13
14
  from polars import DataFrame
@@ -15,30 +16,6 @@ if TYPE_CHECKING:
15
16
  from kabukit.utils.concurrent import Callback, Progress
16
17
 
17
18
 
18
- def get_dates(days: int | None = None, years: int | None = None) -> list[datetime.date]:
19
- """過去days日またはyears年の日付リストを返す。
20
-
21
- Args:
22
- days (int | None): 過去days日の日付リストを取得する。
23
- years (int | None): 過去years年の日付リストを取得する。
24
- daysが指定されている場合は無視される。
25
- """
26
- end_date = datetime.date.today() # noqa: DTZ011
27
-
28
- if days is not None:
29
- start_date = end_date - datetime.timedelta(days=days)
30
- elif years is not None:
31
- start_date = end_date.replace(year=end_date.year - years)
32
- else:
33
- msg = "daysまたはyearsのいずれかを指定してください。"
34
- raise ValueError(msg)
35
-
36
- return [
37
- start_date + datetime.timedelta(days=i)
38
- for i in range(1, (end_date - start_date).days + 1)
39
- ]
40
-
41
-
42
19
  async def fetch(
43
20
  resource: str,
44
21
  args: Iterable[str | datetime.date],
kabukit/jquants/client.py CHANGED
@@ -132,15 +132,18 @@ class JQuantsClient(Client):
132
132
  self,
133
133
  code: str | None = None,
134
134
  date: str | datetime.date | None = None,
135
+ *,
136
+ clean: bool = True,
135
137
  ) -> DataFrame:
136
138
  """銘柄情報を取得する。
137
139
 
138
140
  Args:
139
141
  code (str, optional): 情報を取得する銘柄のコード。
140
142
  date (str | datetime.date, optional): 情報を取得する日付。
143
+ clean (bool, optional): 取得したデータをクリーンアップするかどうか。
141
144
 
142
145
  Returns:
143
- 銘柄情報を含むPolars DataFrame。
146
+ 銘柄情報を含むDataFrame。
144
147
 
145
148
  Raises:
146
149
  HTTPStatusError: APIリクエストが失敗した場合。
@@ -148,7 +151,8 @@ class JQuantsClient(Client):
148
151
  params = get_params(code=code, date=date)
149
152
  url = "/listed/info"
150
153
  data = await self.get(url, params)
151
- return DataFrame(data["info"]).pipe(info.clean)
154
+ df = DataFrame(data["info"])
155
+ return info.clean(df) if clean else df
152
156
 
153
157
  async def iter_pages(
154
158
  self,
@@ -164,7 +168,7 @@ class JQuantsClient(Client):
164
168
  name (str): アイテムのリストを含むJSONレスポンスのキー。
165
169
 
166
170
  Yields:
167
- データの各ページに対応するPolars DataFrame。
171
+ データの各ページに対応するDataFrame。
168
172
 
169
173
  Raises:
170
174
  HTTPStatusError: APIリクエストが失敗した場合。
@@ -185,6 +189,8 @@ class JQuantsClient(Client):
185
189
  date: str | datetime.date | None = None,
186
190
  from_: str | datetime.date | None = None,
187
191
  to: str | datetime.date | None = None,
192
+ *,
193
+ clean: bool = True,
188
194
  ) -> DataFrame:
189
195
  """日々の株価四本値を取得する。
190
196
 
@@ -198,16 +204,17 @@ class JQuantsClient(Client):
198
204
  `date`とは併用不可。
199
205
  to (str | datetime.date, optional): 取得期間の終了日。
200
206
  `date`とは併用不可。
207
+ clean (bool, optional): 取得したデータをクリーンアップするかどうか。
201
208
 
202
209
  Returns:
203
- 日々の株価四本値を含むPolars DataFrame。
210
+ 日々の株価四本値を含むDataFrame。
204
211
 
205
212
  Raises:
206
213
  ValueError: `date`と`from_`/`to`の両方が指定された場合。
207
214
  HTTPStatusError: APIリクエストが失敗した場合。
208
215
  """
209
216
  if not date and not code:
210
- return await self.get_latest_available_prices()
217
+ return await self.get_latest_available_prices(clean=clean)
211
218
 
212
219
  if date and (from_ or to):
213
220
  msg = "dateとfrom/toの両方を指定することはできません。"
@@ -224,15 +231,20 @@ class JQuantsClient(Client):
224
231
  if df.is_empty():
225
232
  return df
226
233
 
227
- return prices.clean(df)
234
+ return prices.clean(df) if clean else df
228
235
 
229
- async def get_latest_available_prices(self, num_days: int = 30) -> DataFrame:
236
+ async def get_latest_available_prices(
237
+ self,
238
+ num_days: int = 30,
239
+ *,
240
+ clean: bool = True,
241
+ ) -> DataFrame:
230
242
  """直近利用可能な日付の株価を取得する。"""
231
243
  today = datetime.date.today() # noqa: DTZ011
232
244
 
233
245
  for days in range(num_days):
234
246
  date = today - datetime.timedelta(days)
235
- df = await self.get_prices(date=date)
247
+ df = await self.get_prices(date=date, clean=clean)
236
248
 
237
249
  if not df.is_empty():
238
250
  return df
@@ -243,12 +255,15 @@ class JQuantsClient(Client):
243
255
  self,
244
256
  code: str | None = None,
245
257
  date: str | datetime.date | None = None,
258
+ *,
259
+ clean: bool = True,
246
260
  ) -> DataFrame:
247
261
  """四半期毎の決算短信サマリーおよび業績・配当の修正に関する開示情報を取得する。
248
262
 
249
263
  Args:
250
264
  code (str, optional): 財務情報を取得する銘柄のコード。
251
265
  date (str | datetime.date, optional): 財務情報を取得する日付。
266
+ clean (bool, optional): 取得したデータをクリーンアップするかどうか。
252
267
 
253
268
  Returns:
254
269
  財務情報を含むDataFrame。
@@ -271,7 +286,7 @@ class JQuantsClient(Client):
271
286
  if df.is_empty():
272
287
  return df
273
288
 
274
- return statements.clean(df)
289
+ return statements.clean(df) if clean else df
275
290
 
276
291
  async def get_announcement(self) -> DataFrame:
277
292
  """翌日発表予定の決算情報を取得する。
@@ -2,25 +2,14 @@ from __future__ import annotations
2
2
 
3
3
  import datetime
4
4
  from functools import cache
5
- from typing import TYPE_CHECKING, Any, Protocol
5
+ from typing import TYPE_CHECKING
6
6
 
7
7
  import holidays
8
8
  import polars as pl
9
9
 
10
10
  if TYPE_CHECKING:
11
- from collections.abc import AsyncIterable, AsyncIterator
12
-
13
11
  from polars import DataFrame
14
12
 
15
- class Progress(Protocol):
16
- def __call__[T](
17
- self,
18
- async_iterable: AsyncIterable[T],
19
- total: int | None = None,
20
- *args: Any,
21
- **kwargs: Any,
22
- ) -> AsyncIterator[T]: ...
23
-
24
13
 
25
14
  def clean(df: DataFrame) -> DataFrame:
26
15
  return (
@@ -23,13 +23,14 @@ if TYPE_CHECKING:
23
23
  from kabukit.core.client import Client
24
24
 
25
25
  class _Progress(Protocol):
26
- def __call__[T](
26
+ def __call__(
27
27
  self,
28
- aiterable: AsyncIterable[T],
28
+ aiterable: AsyncIterable[Any],
29
+ /,
29
30
  total: int | None = None,
30
31
  *args: Any,
31
32
  **kwargs: Any,
32
- ) -> AsyncIterator[T]: ...
33
+ ) -> AsyncIterator[Any]: ...
33
34
 
34
35
 
35
36
  MAX_CONCURRENCY = 12
kabukit/utils/config.py CHANGED
@@ -1,13 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- from functools import cache
4
3
  from pathlib import Path
5
4
 
6
5
  import dotenv
7
6
  from platformdirs import user_config_dir
8
7
 
9
8
 
10
- @cache
11
9
  def get_dotenv_path() -> Path:
12
10
  """Return the path to the .env file in the user config directory."""
13
11
  config_dir = Path(user_config_dir("kabukit"))
@@ -15,12 +13,11 @@ def get_dotenv_path() -> Path:
15
13
  return config_dir / ".env"
16
14
 
17
15
 
18
- @cache
19
- def load_dotenv() -> bool:
16
+ def set_key(key: str, value: str) -> tuple[bool | None, str, str]:
20
17
  dotenv_path = get_dotenv_path()
21
- return dotenv.load_dotenv(dotenv_path)
18
+ return dotenv.set_key(dotenv_path, key, value)
22
19
 
23
20
 
24
- def set_key(key: str, value: str) -> tuple[bool | None, str, str]:
21
+ def load_dotenv() -> bool:
25
22
  dotenv_path = get_dotenv_path()
26
- return dotenv.set_key(dotenv_path, key, value)
23
+ return dotenv.load_dotenv(dotenv_path)
kabukit/utils/date.py ADDED
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+
5
+
6
+ def get_dates(days: int | None = None, years: int | None = None) -> list[datetime.date]:
7
+ """過去days日またはyears年の日付リストを返す。
8
+
9
+ Args:
10
+ days (int | None): 過去days日の日付リストを取得する。
11
+ years (int | None): 過去years年の日付リストを取得する。
12
+ daysが指定されている場合は無視される。
13
+ """
14
+ end_date = datetime.date.today() # noqa: DTZ011
15
+
16
+ if days is not None:
17
+ start_date = end_date - datetime.timedelta(days=days)
18
+ elif years is not None:
19
+ start_date = end_date.replace(year=end_date.year - years)
20
+ else:
21
+ msg = "daysまたはyearsのいずれかを指定してください。"
22
+ raise ValueError(msg)
23
+
24
+ return [
25
+ start_date + datetime.timedelta(days=i)
26
+ for i in range(1, (end_date - start_date).days + 1)
27
+ ]
kabukit/utils/params.py CHANGED
@@ -18,16 +18,16 @@ def iter_items(kwargs: dict[str, Any]) -> Iterator[tuple[str, Any]]:
18
18
  yield key, value
19
19
 
20
20
 
21
- def get_params(**kwargs: Any) -> dict[str, str]:
22
- params: dict[str, str] = {}
21
+ def get_params(**kwargs: Any) -> dict[str, Any]:
22
+ params: dict[str, Any] = {}
23
23
 
24
24
  for key, value in iter_items(kwargs):
25
25
  if isinstance(value, datetime.date):
26
26
  params[key] = date_to_str(value)
27
- elif not isinstance(value, str):
28
- params[key] = str(value)
29
- else:
27
+ elif isinstance(value, str | int | float | bool):
30
28
  params[key] = value
29
+ else:
30
+ params[key] = str(value)
31
31
 
32
32
  return params
33
33
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kabukit
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: A Python toolkit for Japanese financial market data, supporting J-Quants and EDINET APIs.
5
5
  Author: daizutabi
6
6
  Author-email: daizutabi <daizutabi@gmail.com>
@@ -27,21 +27,19 @@ License: MIT License
27
27
  SOFTWARE.
28
28
  Classifier: Development Status :: 4 - Beta
29
29
  Classifier: Programming Language :: Python
30
- Classifier: Programming Language :: Python :: 3.12
31
30
  Classifier: Programming Language :: Python :: 3.13
32
31
  Requires-Dist: altair>=5
33
32
  Requires-Dist: async-typer>=0.1
34
33
  Requires-Dist: holidays>=0.81
35
34
  Requires-Dist: httpx>=0.28.1
36
- Requires-Dist: marimo[lsp]>=0.16
37
35
  Requires-Dist: platformdirs>=4
38
36
  Requires-Dist: polars>=1
39
37
  Requires-Dist: python-dotenv>=1
40
38
  Requires-Dist: typer>=0.19
41
- Requires-Dist: vegafusion-python-embed>=1.6
42
- Requires-Dist: vegafusion>=2
43
- Requires-Dist: vl-convert-python>=1.8
44
- Requires-Python: >=3.12
39
+ Requires-Python: >=3.13
40
+ Project-URL: Documentation, https://daizutabi.github.io/kabukit/
41
+ Project-URL: Issues, https://github.com/daizutabi/kabukit/issues
42
+ Project-URL: Source, https://github.com/daizutabi/kabukit
45
43
  Description-Content-Type: text/markdown
46
44
 
47
45
  # kabukit
@@ -50,6 +48,9 @@ A Python toolkit for Japanese financial market data, supporting J-Quants and EDI
50
48
 
51
49
  [![PyPI Version][pypi-v-image]][pypi-v-link]
52
50
  [![Python Version][python-v-image]][python-v-link]
51
+ [![Build Status][GHAction-image]][GHAction-link]
52
+ [![Coverage Status][codecov-image]][codecov-link]
53
+ [![Documentation Status][docs-image]][docs-link]
53
54
 
54
55
  ## Installation
55
56
 
@@ -58,7 +59,14 @@ pip install kabukit
58
59
  ```
59
60
 
60
61
  <!-- Badges -->
62
+
61
63
  [pypi-v-image]: https://img.shields.io/pypi/v/kabukit.svg
62
64
  [pypi-v-link]: https://pypi.org/project/kabukit/
63
65
  [python-v-image]: https://img.shields.io/pypi/pyversions/kabukit.svg
64
66
  [python-v-link]: https://pypi.org/project/kabukit
67
+ [GHAction-image]: https://github.com/daizutabi/kabukit/actions/workflows/ci.yaml/badge.svg?branch=main&event=push
68
+ [GHAction-link]: https://github.com/daizutabi/kabukit/actions?query=event%3Apush+branch%3Amain
69
+ [codecov-image]: https://codecov.io/github/daizutabi/kabukit/graph/badge.svg?token=Yu6lAdVVnd
70
+ [codecov-link]: https://codecov.io/github/daizutabi/kabukit?branch=main
71
+ [docs-image]: https://img.shields.io/badge/docs-latest-blue.svg
72
+ [docs-link]: https://daizutabi.github.io/kabukit/
@@ -5,31 +5,33 @@ kabukit/analysis/preprocess.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
5
5
  kabukit/analysis/screener.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  kabukit/analysis/visualization.py,sha256=VS9WXBKcdOYsnVe-OR3cWP_nru3Oa-rBOK5SUwsxfyQ,1857
7
7
  kabukit/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- kabukit/cli/app.py,sha256=LjAq_Pj5_bokL4bCZ2R8OoP_zEBA-a2EG0Pm1ZCn7o8,491
8
+ kabukit/cli/app.py,sha256=HKzxE2ue_VvdVazCFcU25PmDs3LJIjKvO7l-jdYJV_E,531
9
9
  kabukit/cli/auth.py,sha256=MWLxEiINrqMGJSiVHcv09EuPlyGeCitHqJq7kumzbr8,2735
10
+ kabukit/cli/get.py,sha256=-qeoy6XRqj6fdGcTRPaA-ZAJlGFWMK7QOFNVeEtSPeM,2913
10
11
  kabukit/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- kabukit/core/base.py,sha256=kqaqtYHHFK8xC3z8QkLFv8CAV6FEZDDoiVY2Qwe9iM8,1125
12
+ kabukit/core/base.py,sha256=SSUPzcFot0shN5nRY4cKN_Rt13TBBcyxHwqqwT-vcac,1280
12
13
  kabukit/core/client.py,sha256=lvjrshzOjyea2jRmc11Dl5OAJUGGN3PfKXWxoveG6hY,664
13
14
  kabukit/core/info.py,sha256=5BX7mDavF6g-b0KzHgKIFHUS5701BoaHtw1JcHSsy94,174
14
15
  kabukit/core/prices.py,sha256=Axm9cceVxnHIWCW6IHqEuCC4M73JtWCRzjXA42Qd7JE,781
15
16
  kabukit/core/statements.py,sha256=18vD5WRjBGVSXvmCfTvGAwgjnajLbN-tH6V91sX44iI,94
16
17
  kabukit/edinet/__init__.py,sha256=9bAWDIgVZKw84GF4z6FilUP_B22ih-ixLm8cQHxaoS8,77
17
18
  kabukit/edinet/client.py,sha256=OSz8BmSBzzZMD-wk_9WbhZLfDY901s5CN1UissoDtyc,3410
18
- kabukit/edinet/concurrent.py,sha256=du4TG0WwfkiWvxznXh-P0u1E_8mjTHBNivCIVmpieUg,5496
19
+ kabukit/edinet/concurrent.py,sha256=RCNiD1hCP0Yat78IzfF4709tn_QgD1CTS17g_fNl7ZQ,4656
19
20
  kabukit/edinet/doc.py,sha256=ieze_886Tzkp6QYRJD3GuSXj6-LS43MqmA72zEx1kjA,959
20
21
  kabukit/jquants/__init__.py,sha256=n-sg0pLajSfyJ8snU6I_Q52rwmuaGCwAyz1yVbeMSw4,75
21
- kabukit/jquants/client.py,sha256=nyBAD2hspz_bLtkTLUgFGGRz9oZXXkXONV1exjW9O1s,10704
22
+ kabukit/jquants/client.py,sha256=cszePJwByMgDJ4hFGrkEQeWchRb2HsNS48dzePKl7Kk,11257
22
23
  kabukit/jquants/concurrent.py,sha256=5XObYKMMYNmrq-8JLtVg0uBGoEJwI9Luvy6ndamiTz8,3288
23
24
  kabukit/jquants/info.py,sha256=AUymo6EtLdJ_L-0yNG1gd7rJ8Jkjw7tvsDM5Vw4QNFA,843
24
25
  kabukit/jquants/prices.py,sha256=oApQpdgzHwPw11XHpdg8ccZS7kybGtV8APZlpD2L3Yw,882
25
26
  kabukit/jquants/schema.py,sha256=HIoKDoIWrT0XNDHz5Fm4DtDGLLRqrq6TIkMTvq_Jheg,9647
26
- kabukit/jquants/statements.py,sha256=rPfIVJjWeEviWEtjPRUGesHyIpQKMfBxDLTXJzkYBdA,2995
27
+ kabukit/jquants/statements.py,sha256=H-Ymat2gqAOsTaBNPtqLj8-5MLda72UkJW8SK2PvD5Q,2674
27
28
  kabukit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
29
  kabukit/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- kabukit/utils/concurrent.py,sha256=7eXk29IhDLGroCCMIb8ucVqLMV9tYh0o2jYCoAU5tVM,4494
30
- kabukit/utils/config.py,sha256=Bsa_BGxNsHyaLWkC99oliRRPmkv5K0YKSdYF-ADGjck,660
31
- kabukit/utils/params.py,sha256=a5QLxTyB6jegeXDerQNmpYEKdZplhL3GnJuK0WRbBtQ,1091
32
- kabukit-0.2.0.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
33
- kabukit-0.2.0.dist-info/entry_points.txt,sha256=vvX771TemoM-35vVizW3JJ70HvRXnd2tX4P1Btzyoxs,46
34
- kabukit-0.2.0.dist-info/METADATA,sha256=SuzdQfFqziFhEsJq_8v4UQ91XIkQhgp3qKRiayZh3uk,2584
35
- kabukit-0.2.0.dist-info/RECORD,,
30
+ kabukit/utils/concurrent.py,sha256=m2zVqJUz4xFVpNbEc9YEaj3Jmbl82njupdm4_rBOoYQ,4510
31
+ kabukit/utils/config.py,sha256=Jp-2TCnIj_QqA71FzYCkHXbvXvhw_1JVl4PR0foA1vM,618
32
+ kabukit/utils/date.py,sha256=DEC6Ac5LS8eiW6JtrmcD3U1pX4qzXtx4ale0swpO4Ag,937
33
+ kabukit/utils/params.py,sha256=qcaJbf6CWPUoZAZsYDTaZSnBUWeAersbWnR_iiYW9GM,1108
34
+ kabukit-0.3.0.dist-info/WHEEL,sha256=-neZj6nU9KAMg2CnCY6T3w8J53nx1kFGw_9HfoSzM60,79
35
+ kabukit-0.3.0.dist-info/entry_points.txt,sha256=vvX771TemoM-35vVizW3JJ70HvRXnd2tX4P1Btzyoxs,46
36
+ kabukit-0.3.0.dist-info/METADATA,sha256=UiJ_0PCOg-ghUW5iCdh7Tpxy4-NtgGChhzGI7gkoncM,3214
37
+ kabukit-0.3.0.dist-info/RECORD,,