kabukit 0.7.6__tar.gz → 0.8.1__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 (48) hide show
  1. kabukit-0.8.1/PKG-INFO +113 -0
  2. kabukit-0.8.1/README.md +52 -0
  3. {kabukit-0.7.6 → kabukit-0.8.1}/pyproject.toml +15 -6
  4. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/__init__.py +2 -4
  5. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/cli/auth.py +1 -1
  6. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/cli/cache.py +13 -1
  7. kabukit-0.8.1/src/kabukit/cli/get.py +156 -0
  8. kabukit-0.7.6/src/kabukit/core/list.py → kabukit-0.8.1/src/kabukit/core/documents.py +1 -1
  9. kabukit-0.8.1/src/kabukit/edinet/__init__.py +3 -0
  10. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/edinet/client.py +20 -3
  11. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/edinet/concurrent.py +6 -6
  12. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/edinet/doc.py +3 -2
  13. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/info.py +1 -0
  14. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/concurrent.py +1 -1
  15. kabukit-0.7.6/PKG-INFO +0 -260
  16. kabukit-0.7.6/README.md +0 -200
  17. kabukit-0.7.6/src/kabukit/cli/get.py +0 -169
  18. kabukit-0.7.6/src/kabukit/core/reports.py +0 -7
  19. kabukit-0.7.6/src/kabukit/edinet/__init__.py +0 -3
  20. {kabukit-0.7.6 → kabukit-0.8.1}/LICENSE +0 -0
  21. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/__init__.py +0 -0
  22. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/indicators.py +0 -0
  23. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/preprocess.py +0 -0
  24. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/screener.py +0 -0
  25. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/visualization/__init__.py +0 -0
  26. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/visualization/market.py +0 -0
  27. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/analysis/visualization/prices.py +0 -0
  28. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/cli/__init__.py +0 -0
  29. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/cli/app.py +0 -0
  30. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/__init__.py +0 -0
  31. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/base.py +0 -0
  32. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/client.py +0 -0
  33. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/info.py +0 -0
  34. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/prices.py +0 -0
  35. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/core/statements.py +0 -0
  36. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/__init__.py +0 -0
  37. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/calendar.py +0 -0
  38. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/client.py +0 -0
  39. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/concurrent.py +0 -0
  40. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/prices.py +0 -0
  41. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/schema.py +0 -0
  42. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/statements.py +0 -0
  43. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/jquants/topix.py +0 -0
  44. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/py.typed +0 -0
  45. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/__init__.py +0 -0
  46. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/config.py +0 -0
  47. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/date.py +0 -0
  48. {kabukit-0.7.6 → kabukit-0.8.1}/src/kabukit/utils/params.py +0 -0
kabukit-0.8.1/PKG-INFO ADDED
@@ -0,0 +1,113 @@
1
+ Metadata-Version: 2.3
2
+ Name: kabukit
3
+ Version: 0.8.1
4
+ Summary: A Python toolkit for Japanese financial market data, supporting J-Quants and EDINET APIs.
5
+ Keywords: J-Quants,EDINET,financial data,stock market,investment,toolkit,finance,trading,data analysis,polars
6
+ Author: daizutabi
7
+ Author-email: daizutabi <daizutabi@gmail.com>
8
+ License: MIT License
9
+
10
+ Copyright (c) 2025 Daizu
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ Classifier: Development Status :: 4 - Beta
30
+ Classifier: Programming Language :: Python
31
+ Classifier: Programming Language :: Python :: 3 :: Only
32
+ Classifier: Programming Language :: Python :: 3.12
33
+ Classifier: Programming Language :: Python :: 3.13
34
+ Classifier: Programming Language :: Python :: 3.14
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: Intended Audience :: Financial and Insurance Industry
39
+ Classifier: Intended Audience :: Science/Research
40
+ Classifier: Topic :: Office/Business :: Financial
41
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
42
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
43
+ Classifier: Topic :: Utilities
44
+ Requires-Dist: async-typer>=0.1.10
45
+ Requires-Dist: httpx>=0.28.1
46
+ Requires-Dist: platformdirs>=4.5.0
47
+ Requires-Dist: polars>=1.34.0
48
+ Requires-Dist: python-dotenv>=1.1.1
49
+ Requires-Dist: rich>=14.2.0
50
+ Requires-Dist: tenacity>=9.1.2
51
+ Requires-Dist: tqdm>=4.67.1
52
+ Requires-Dist: typer>=0.19.2
53
+ Requires-Dist: tzdata ; sys_platform == 'win32'
54
+ Requires-Python: >=3.12
55
+ Project-URL: Changelog, https://github.com/daizutabi/kabukit/releases
56
+ Project-URL: Documentation, https://daizutabi.github.io/kabukit/
57
+ Project-URL: Homepage, https://daizutabi.github.io/kabukit/
58
+ Project-URL: Issues, https://github.com/daizutabi/kabukit/issues
59
+ Project-URL: Source, https://github.com/daizutabi/kabukit
60
+ Description-Content-Type: text/markdown
61
+
62
+ # kabukit
63
+
64
+ [![PyPI Version][pypi-v-image]][pypi-v-link]
65
+ [![Python Version][python-v-image]][python-v-link]
66
+ [![Build Status][GHAction-image]][GHAction-link]
67
+ [![Coverage Status][codecov-image]][codecov-link]
68
+ [![Documentation Status][docs-image]][docs-link]
69
+
70
+ A Python toolkit for Japanese financial market data,
71
+ supporting J-Quants and EDINET APIs.
72
+
73
+ kabukit は、 [J-Quants API](https://jpx-jquants.com/) および [EDINET API](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WZEK0110.html) から、効率的に日本の金融市場データを取得するツールキットです。
74
+
75
+ 高速なデータ処理ライブラリである [Polars](https://pola.rs/) と、モダンな非同期 HTTP クライアントである [httpx](https://www.python-httpx.org/) を基盤として構築されており、パフォーマンスを重視しています。
76
+
77
+ ## インストール
78
+
79
+ `pip` または `uv` を使ってインストールします。Python バージョンは 3.12 以上が必要です。
80
+
81
+ ```bash
82
+ pip install kabukit
83
+ ```
84
+
85
+ ## コマンドラインから使う
86
+
87
+ kabukit は、 [J-Quants API](https://jpx-jquants.com/) および [EDINET API](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WZEK0110.html) からデータを取得するための便利なコマンドラインインターフェース(CLI)を提供します。
88
+
89
+ 具体的な使い方は、次の利用ガイドを参照してください。
90
+
91
+ - [コマンドラインインターフェースの使い方](https://daizutabi.github.io/kabukit/guides/cli/)
92
+
93
+ ## ノートブックから使う
94
+
95
+ kabukit は、コマンドラインだけでなく、Python コードからも API として利用できます。httpx を使って非同期でデータを取得するため、[Jupyter](https://jupyter.org/) や [marimo](https://marimo.io/) のような非同期処理を直接扱えるノートブック環境と非常に相性が良いです。
96
+
97
+ 具体的な使い方は、以下の利用ガイドを参照してください。
98
+
99
+ - [J-Quants API の使い方](https://daizutabi.github.io/kabukit/guides/jquants/)
100
+ - [EDINET API の使い方](https://daizutabi.github.io/kabukit/guides/edinet/)
101
+
102
+ <!-- Badges -->
103
+
104
+ [pypi-v-image]: https://img.shields.io/pypi/v/kabukit.svg
105
+ [pypi-v-link]: https://pypi.org/project/kabukit/
106
+ [python-v-image]: https://img.shields.io/pypi/pyversions/kabukit.svg
107
+ [python-v-link]: https://pypi.org/project/kabukit
108
+ [GHAction-image]: https://github.com/daizutabi/kabukit/actions/workflows/ci.yaml/badge.svg?branch=main&event=push
109
+ [GHAction-link]: https://github.com/daizutabi/kabukit/actions?query=event%3Apush+branch%3Amain
110
+ [codecov-image]: https://codecov.io/github/daizutabi/kabukit/graph/badge.svg?token=Yu6lAdVVnd
111
+ [codecov-link]: https://codecov.io/github/daizutabi/kabukit?branch=main
112
+ [docs-image]: https://img.shields.io/badge/docs-latest-blue.svg
113
+ [docs-link]: https://daizutabi.github.io/kabukit/
@@ -0,0 +1,52 @@
1
+ # kabukit
2
+
3
+ [![PyPI Version][pypi-v-image]][pypi-v-link]
4
+ [![Python Version][python-v-image]][python-v-link]
5
+ [![Build Status][GHAction-image]][GHAction-link]
6
+ [![Coverage Status][codecov-image]][codecov-link]
7
+ [![Documentation Status][docs-image]][docs-link]
8
+
9
+ A Python toolkit for Japanese financial market data,
10
+ supporting J-Quants and EDINET APIs.
11
+
12
+ kabukit は、 [J-Quants API](https://jpx-jquants.com/) および [EDINET API](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WZEK0110.html) から、効率的に日本の金融市場データを取得するツールキットです。
13
+
14
+ 高速なデータ処理ライブラリである [Polars](https://pola.rs/) と、モダンな非同期 HTTP クライアントである [httpx](https://www.python-httpx.org/) を基盤として構築されており、パフォーマンスを重視しています。
15
+
16
+ ## インストール
17
+
18
+ `pip` または `uv` を使ってインストールします。Python バージョンは 3.12 以上が必要です。
19
+
20
+ ```bash
21
+ pip install kabukit
22
+ ```
23
+
24
+ ## コマンドラインから使う
25
+
26
+ kabukit は、 [J-Quants API](https://jpx-jquants.com/) および [EDINET API](https://disclosure2dl.edinet-fsa.go.jp/guide/static/disclosure/WZEK0110.html) からデータを取得するための便利なコマンドラインインターフェース(CLI)を提供します。
27
+
28
+ 具体的な使い方は、次の利用ガイドを参照してください。
29
+
30
+ - [コマンドラインインターフェースの使い方](https://daizutabi.github.io/kabukit/guides/cli/)
31
+
32
+ ## ノートブックから使う
33
+
34
+ kabukit は、コマンドラインだけでなく、Python コードからも API として利用できます。httpx を使って非同期でデータを取得するため、[Jupyter](https://jupyter.org/) や [marimo](https://marimo.io/) のような非同期処理を直接扱えるノートブック環境と非常に相性が良いです。
35
+
36
+ 具体的な使い方は、以下の利用ガイドを参照してください。
37
+
38
+ - [J-Quants API の使い方](https://daizutabi.github.io/kabukit/guides/jquants/)
39
+ - [EDINET API の使い方](https://daizutabi.github.io/kabukit/guides/edinet/)
40
+
41
+ <!-- Badges -->
42
+
43
+ [pypi-v-image]: https://img.shields.io/pypi/v/kabukit.svg
44
+ [pypi-v-link]: https://pypi.org/project/kabukit/
45
+ [python-v-image]: https://img.shields.io/pypi/pyversions/kabukit.svg
46
+ [python-v-link]: https://pypi.org/project/kabukit
47
+ [GHAction-image]: https://github.com/daizutabi/kabukit/actions/workflows/ci.yaml/badge.svg?branch=main&event=push
48
+ [GHAction-link]: https://github.com/daizutabi/kabukit/actions?query=event%3Apush+branch%3Amain
49
+ [codecov-image]: https://codecov.io/github/daizutabi/kabukit/graph/badge.svg?token=Yu6lAdVVnd
50
+ [codecov-link]: https://codecov.io/github/daizutabi/kabukit?branch=main
51
+ [docs-image]: https://img.shields.io/badge/docs-latest-blue.svg
52
+ [docs-link]: https://daizutabi.github.io/kabukit/
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "kabukit"
7
- version = "0.7.6"
7
+ version = "0.8.1"
8
8
  description = "A Python toolkit for Japanese financial market data, supporting J-Quants and EDINET APIs."
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -25,6 +25,7 @@ classifiers = [
25
25
  "Development Status :: 4 - Beta",
26
26
  "Programming Language :: Python",
27
27
  "Programming Language :: Python :: 3 :: Only",
28
+ "Programming Language :: Python :: 3.12",
28
29
  "Programming Language :: Python :: 3.13",
29
30
  "Programming Language :: Python :: 3.14",
30
31
  "License :: OSI Approved :: MIT License",
@@ -37,7 +38,7 @@ classifiers = [
37
38
  "Topic :: Scientific/Engineering :: Information Analysis",
38
39
  "Topic :: Utilities",
39
40
  ]
40
- requires-python = ">=3.13"
41
+ requires-python = ">=3.12"
41
42
  dependencies = [
42
43
  "async-typer>=0.1.10",
43
44
  "httpx>=0.28.1",
@@ -65,8 +66,7 @@ Source = "https://github.com/daizutabi/kabukit"
65
66
  dev = [
66
67
  "altair @ git+https://github.com/vega/altair.git@main",
67
68
  "basedpyright>=1.31.6",
68
- "marimo[lsp]>=0.16.5",
69
- "numpy>=2.3.3",
69
+ "marimo[lsp,mcp]>=0.16.5",
70
70
  "pre-commit>=4.3.0",
71
71
  "pytest-asyncio>=1.2.0",
72
72
  "pytest-clarity>=1.0.1",
@@ -79,7 +79,16 @@ dev = [
79
79
  "vegafusion>=2.0.3",
80
80
  "vl-convert-python>=1.8.0",
81
81
  ]
82
- docs = ["mkapi>=4.4", "mkdocs-marimo", "mkdocs-material"]
82
+ docs = [
83
+ "ipykernel>=6.30.1",
84
+ "markdown-exec[ansi]>=1.11.0",
85
+ "mkapi>=4.5",
86
+ "mkdocs-material>=9.6.21",
87
+ "mkdocs-nbsync>=0.1.5",
88
+ "mkdocs-typer>=0.0.3",
89
+ "nbconvert>=7.16.6",
90
+ "pymdownx-cjk-autojoin>=0.2.1",
91
+ ]
83
92
 
84
93
  [tool.pytest.ini_options]
85
94
  addopts = ["--cov=kabukit", "--cov-report=lcov:lcov.info", "--doctest-modules"]
@@ -95,7 +104,7 @@ skip_covered = true
95
104
 
96
105
  [tool.ruff]
97
106
  line-length = 88
98
- target-version = "py313"
107
+ target-version = "py312"
99
108
  include = ["src/**/*.py", "tests/**/*.py"]
100
109
 
101
110
  [tool.ruff.lint]
@@ -1,17 +1,15 @@
1
+ from .core.documents import Documents
1
2
  from .core.info import Info
2
- from .core.list import List
3
3
  from .core.prices import Prices
4
- from .core.reports import Reports
5
4
  from .core.statements import Statements
6
5
  from .edinet.client import EdinetClient
7
6
  from .jquants.client import JQuantsClient
8
7
 
9
8
  __all__ = [
9
+ "Documents",
10
10
  "EdinetClient",
11
11
  "Info",
12
12
  "JQuantsClient",
13
- "List",
14
13
  "Prices",
15
- "Reports",
16
14
  "Statements",
17
15
  ]
@@ -78,7 +78,7 @@ def show() -> None:
78
78
  from kabukit.utils.config import get_dotenv_path
79
79
 
80
80
  path = get_dotenv_path()
81
- typer.echo(f"Configuration file: {path}")
81
+ typer.echo(f"設定ファイル: {path}")
82
82
 
83
83
  if path.exists():
84
84
  config = dotenv_values(path)
@@ -23,7 +23,9 @@ def add_to_tree(tree: Tree, path: Path) -> None:
23
23
  branch = tree.add(p.name)
24
24
  add_to_tree(branch, p)
25
25
  else:
26
- tree.add(p.name)
26
+ size = p.stat().st_size
27
+ formatted_size = format_size(size)
28
+ tree.add(f"{p.name} ({formatted_size})")
27
29
 
28
30
 
29
31
  @app.command()
@@ -59,3 +61,13 @@ def clean() -> None:
59
61
  msg += "エラーが発生しました。"
60
62
  typer.secho(msg, fg=typer.colors.RED, bold=True)
61
63
  raise typer.Exit(1) from None
64
+
65
+
66
+ def format_size(size_in_bytes: int) -> str:
67
+ if size_in_bytes < 1024:
68
+ return f"{size_in_bytes} B"
69
+
70
+ if size_in_bytes < 1024 * 1024:
71
+ return f"{size_in_bytes / 1024:.1f} KB"
72
+
73
+ return f"{size_in_bytes / (1024 * 1024):.1f} MB"
@@ -0,0 +1,156 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Annotated, Any
4
+
5
+ import typer
6
+ from async_typer import AsyncTyper
7
+ from typer import Argument, Option
8
+
9
+ if TYPE_CHECKING:
10
+ from kabukit.core.base import Base
11
+
12
+ # pyright: reportMissingTypeStubs=false
13
+ # pyright: reportUnknownMemberType=false
14
+
15
+ app = AsyncTyper(
16
+ add_completion=False,
17
+ help="J-Quantsからデータを取得します。",
18
+ )
19
+
20
+ Code = Annotated[
21
+ str | None,
22
+ Argument(help="銘柄コード。指定しない場合は全銘柄の情報を取得します。"),
23
+ ]
24
+ Quiet = Annotated[
25
+ bool,
26
+ Option("--quiet", "-q", help="プログレスバーを表示しません。"),
27
+ ]
28
+
29
+
30
+ @app.async_command()
31
+ async def info(code: Code = None, *, quiet: Quiet = False) -> None:
32
+ """上場銘柄一覧を取得します。"""
33
+ from kabukit.core.info import Info
34
+ from kabukit.jquants.client import JQuantsClient
35
+
36
+ async with JQuantsClient() as client:
37
+ df = await client.get_info(code)
38
+
39
+ if code or not quiet:
40
+ typer.echo(df)
41
+
42
+ if code is None:
43
+ path = Info(df).write()
44
+ typer.echo(f"全銘柄の情報を '{path}' に保存しました。")
45
+
46
+
47
+ async def _fetch(
48
+ code: str | None,
49
+ target: str,
50
+ cls: type[Base],
51
+ fetch_func_name: str,
52
+ message: str,
53
+ *,
54
+ quiet: bool = False,
55
+ **kwargs: Any,
56
+ ) -> None:
57
+ """財務情報・株価情報を取得するための共通処理"""
58
+ from kabukit.jquants.client import JQuantsClient
59
+
60
+ if code is not None:
61
+ async with JQuantsClient() as client:
62
+ df = await getattr(client, fetch_func_name)(code)
63
+ typer.echo(df)
64
+ return
65
+
66
+ import tqdm.asyncio
67
+
68
+ from kabukit.jquants.concurrent import fetch_all
69
+
70
+ progress = None if quiet else tqdm.asyncio.tqdm
71
+
72
+ try:
73
+ df = await fetch_all(target, progress=progress, **kwargs)
74
+ except KeyboardInterrupt:
75
+ typer.echo("中断しました。")
76
+ raise typer.Exit(1) from None
77
+
78
+ if not quiet:
79
+ typer.echo(df)
80
+
81
+ path = cls(df).write()
82
+ typer.echo(f"全銘柄の{message}を '{path}' に保存しました。")
83
+
84
+
85
+ @app.async_command()
86
+ async def statements(code: Code = None, *, quiet: Quiet = False) -> None:
87
+ """財務情報を取得します。"""
88
+ from kabukit.core.statements import Statements
89
+
90
+ await _fetch(
91
+ code=code,
92
+ target="statements",
93
+ cls=Statements,
94
+ fetch_func_name="get_statements",
95
+ message="財務情報",
96
+ quiet=quiet,
97
+ )
98
+
99
+
100
+ @app.async_command()
101
+ async def prices(code: Code = None, *, quiet: Quiet = False) -> None:
102
+ """株価情報を取得します。"""
103
+ from kabukit.core.prices import Prices
104
+
105
+ await _fetch(
106
+ code=code,
107
+ target="prices",
108
+ cls=Prices,
109
+ fetch_func_name="get_prices",
110
+ message="株価情報",
111
+ quiet=quiet,
112
+ max_concurrency=8,
113
+ )
114
+
115
+
116
+ @app.async_command()
117
+ async def documents(*, quiet: Quiet = False) -> None:
118
+ """書類一覧を取得します。"""
119
+ import tqdm.asyncio
120
+
121
+ from kabukit.core.documents import Documents
122
+ from kabukit.edinet.concurrent import fetch_documents
123
+
124
+ progress = None if quiet else tqdm.asyncio.tqdm
125
+
126
+ try:
127
+ df = await fetch_documents(years=10, progress=progress)
128
+ except (KeyboardInterrupt, RuntimeError):
129
+ typer.echo("中断しました。")
130
+ raise typer.Exit(1) from None
131
+
132
+ if not quiet:
133
+ typer.echo(df)
134
+
135
+ path = Documents(df).write()
136
+ typer.echo(f"書類一覧を '{path}' に保存しました。")
137
+
138
+
139
+ @app.async_command(name="all")
140
+ async def all_(code: Code = None, *, quiet: Quiet = False) -> None:
141
+ """上場銘柄一覧、財務情報、株価情報、書類一覧を連続して取得します。"""
142
+ typer.echo("上場銘柄一覧を取得します。")
143
+ await info(code, quiet=quiet)
144
+
145
+ typer.echo("---")
146
+ typer.echo("財務情報を取得します。")
147
+ await statements(code, quiet=quiet)
148
+
149
+ typer.echo("---")
150
+ typer.echo("株価情報を取得します。")
151
+ await prices(code, quiet=quiet)
152
+
153
+ if code is None:
154
+ typer.echo("---")
155
+ typer.echo("書類一覧を取得します。")
156
+ await documents(quiet=quiet)
@@ -3,5 +3,5 @@ from __future__ import annotations
3
3
  from .base import Base
4
4
 
5
5
 
6
- class List(Base):
6
+ class Documents(Base):
7
7
  pass
@@ -0,0 +1,3 @@
1
+ from .concurrent import fetch, fetch_csv, fetch_documents
2
+
3
+ __all__ = ["fetch", "fetch_csv", "fetch_documents"]
@@ -14,7 +14,7 @@ from kabukit.core.client import Client
14
14
  from kabukit.utils.config import load_dotenv
15
15
  from kabukit.utils.params import get_params
16
16
 
17
- from .doc import clean_csv, clean_list, read_csv
17
+ from .doc import clean_csv, clean_documents, read_csv
18
18
 
19
19
  if TYPE_CHECKING:
20
20
  import datetime
@@ -62,6 +62,15 @@ class EdinetClient(Client):
62
62
  return resp
63
63
 
64
64
  async def get_count(self, date: str | datetime.date) -> int:
65
+ """書類一覧 API を使い、特定の日付の提出書類数を取得する。
66
+
67
+ Args:
68
+ date (str | datetime.date): 取得対象の日付 (YYYY-MM-DD)
69
+
70
+ Returns:
71
+ int: 書類数
72
+
73
+ """
65
74
  params = get_params(date=date, type=1)
66
75
  resp = await self.get("/documents.json", params)
67
76
  data = resp.json()
@@ -72,7 +81,15 @@ class EdinetClient(Client):
72
81
 
73
82
  return metadata["resultset"]["count"]
74
83
 
75
- async def get_list(self, date: str | datetime.date) -> DataFrame:
84
+ async def get_documents(self, date: str | datetime.date) -> DataFrame:
85
+ """書類一覧 API を使い、特定の日付の提出書類一覧を取得する。
86
+
87
+ Args:
88
+ date (str | datetime.date): 取得対象の日付 (YYYY-MM-DD)
89
+
90
+ Returns:
91
+ DataFrame: 提出書類一覧を格納した DataFrame
92
+ """
76
93
  params = get_params(date=date, type=2)
77
94
  resp = await self.get("/documents.json", params)
78
95
  data = resp.json()
@@ -85,7 +102,7 @@ class EdinetClient(Client):
85
102
  if df.is_empty():
86
103
  return df
87
104
 
88
- return clean_list(df, date)
105
+ return clean_documents(df, date)
89
106
 
90
107
  async def get_document(self, doc_id: str, doc_type: int) -> Response:
91
108
  params = get_params(type=doc_type)
@@ -52,7 +52,7 @@ async def fetch(
52
52
  )
53
53
 
54
54
 
55
- async def fetch_list(
55
+ async def fetch_documents(
56
56
  days: int | None = None,
57
57
  years: int | None = None,
58
58
  limit: int | None = None,
@@ -60,11 +60,11 @@ async def fetch_list(
60
60
  progress: Progress | None = None,
61
61
  callback: Callback | None = None,
62
62
  ) -> DataFrame:
63
- """過去days日またはyears年の文書一覧を取得し、単一のDataFrameにまとめて返す。
63
+ """過去 days 日または years 年の文書一覧を取得し、単一の DataFrame にまとめて返す。
64
64
 
65
65
  Args:
66
- days (int | None): 過去days日の日付リストを取得する。
67
- years (int | None): 過去years年の日付リストを取得する。
66
+ days (int | None): 過去 days 日の日付リストを取得する。
67
+ years (int | None): 過去 years 年の日付リストを取得する。
68
68
  daysが指定されている場合は無視される。
69
69
  max_concurrency (int | None, optional): 同時に実行するリクエストの最大数。
70
70
  指定しないときはデフォルト値が使用される。
@@ -84,13 +84,13 @@ async def fetch_list(
84
84
  dates = dates[:limit]
85
85
 
86
86
  df = await fetch(
87
- "list",
87
+ "documents",
88
88
  dates,
89
89
  max_concurrency=max_concurrency,
90
90
  progress=progress,
91
91
  callback=callback,
92
92
  )
93
- return df.sort("Date")
93
+ return df.sort("Date", "Code")
94
94
 
95
95
 
96
96
  async def fetch_csv(
@@ -10,7 +10,7 @@ if TYPE_CHECKING:
10
10
  from polars import DataFrame
11
11
 
12
12
 
13
- def clean_list(df: DataFrame, date: str | datetime.date) -> DataFrame:
13
+ def clean_documents(df: DataFrame, date: str | datetime.date) -> DataFrame:
14
14
  if isinstance(date, str):
15
15
  date = (
16
16
  datetime.datetime.strptime(date, "%Y-%m-%d")
@@ -35,7 +35,8 @@ def clean_list(df: DataFrame, date: str | datetime.date) -> DataFrame:
35
35
  pl.col("^.+Flag$").cast(pl.Int8).cast(pl.Boolean),
36
36
  pl.col("^.+Code$").cast(pl.String),
37
37
  )
38
- .select("Date", pl.exclude("Date"))
38
+ .rename({"secCode": "Code"})
39
+ .select("Date", "Code", pl.exclude("Date", "Code"))
39
40
  )
40
41
 
41
42
 
@@ -15,6 +15,7 @@ async def get_target_codes() -> list[str]:
15
15
  """分析対象となる銘柄コードのリストを返す。
16
16
 
17
17
  以下の条件を満たす銘柄は対象外とする。
18
+
18
19
  - 市場: TOKYO PRO MARKET
19
20
  - 業種: その他 -- (投資信託など)
20
21
  - 優先株式
@@ -51,7 +51,7 @@ async def collect[R](
51
51
  tasks = {asyncio.create_task(run(awaitable)) for awaitable in awaitables}
52
52
 
53
53
  try:
54
- async for future in asyncio.as_completed(tasks):
54
+ for future in asyncio.as_completed(tasks): # async for (python 3.13+)
55
55
  with contextlib.suppress(asyncio.CancelledError):
56
56
  yield await future
57
57
  finally: