quantdb-sdk 0.1.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.
@@ -0,0 +1,22 @@
1
+ # MANIFEST.in - 确保发布到 PyPI 时包含必要的非 Python 文件
2
+
3
+ # 包含 README 和许可证
4
+ include README.md
5
+ include LICENSE
6
+
7
+ # 包含依赖文件
8
+ include requirements.txt
9
+
10
+ # 包含类型标记文件
11
+ include quantdb_sdk/py.typed
12
+
13
+ # 排除不需要的文件
14
+ exclude .gitignore
15
+ exclude Makefile
16
+ recursive-exclude tests *
17
+ recursive-exclude .github *
18
+ recursive-exclude docs *
19
+ recursive-exclude website *
20
+ recursive-exclude frontend *
21
+ recursive-exclude backend *
22
+ recursive-exclude pipeline *
@@ -0,0 +1,93 @@
1
+ Metadata-Version: 2.4
2
+ Name: quantdb-sdk
3
+ Version: 0.1.0
4
+ Summary: QuantDB 量化数据平台官方 Python SDK
5
+ Author: QuantDB Team
6
+ License: MIT
7
+ Project-URL: Homepage, https://www.quantmindai.cn
8
+ Project-URL: Documentation, https://www.quantmindai.cn/docs/sdk.html
9
+ Project-URL: Repository, https://github.com/quantdb/quantdb
10
+ Keywords: quant,finance,data,a-share,parquet
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Financial and Insurance Industry
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Office/Business :: Financial
22
+ Requires-Python: >=3.8
23
+ Description-Content-Type: text/markdown
24
+ Requires-Dist: requests>=2.25.0
25
+ Requires-Dist: pandas>=1.3.0
26
+ Requires-Dist: httpx>=0.24.0
27
+ Requires-Dist: duckdb>=0.8.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
30
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
31
+ Requires-Dist: responses>=0.23.0; extra == "dev"
32
+ Requires-Dist: respx>=0.20.0; extra == "dev"
33
+
34
+ # QuantDB Python SDK
35
+
36
+ QuantDB 量化数据平台官方 Python SDK,提供同步与异步两种客户端,封装了全部 API 端点。
37
+
38
+ ## 安装
39
+
40
+ ```bash
41
+ pip install quantdb-sdk
42
+ ```
43
+
44
+ 开发依赖:
45
+
46
+ ```bash
47
+ pip install -e ".[dev]"
48
+ ```
49
+
50
+ ## 快速开始
51
+
52
+ ### API Key 鉴权(推荐)
53
+
54
+ ```python
55
+ from quantdb_sdk import QuantDBClient
56
+
57
+ client = QuantDBClient(api_key="qdb_xxx...")
58
+
59
+ # 查询用量
60
+ usage = client.get_usage()
61
+ print(f"已用: {usage['used_gb']:.2f} GB, 剩余: {usage['remaining_gb']:.2f} GB")
62
+
63
+ # K 线查询(免费)
64
+ df = client.query_kline(
65
+ "600519.SH",
66
+ adj_type="forward",
67
+ start_date="2026-01-01",
68
+ end_date="2026-07-22",
69
+ )
70
+ print(df.head())
71
+ ```
72
+
73
+ ### 用户名密码鉴权
74
+
75
+ ```python
76
+ client = QuantDBClient(username="admin", password="admin123")
77
+ ```
78
+
79
+ ## 核心功能
80
+
81
+ - **数据查询**:K 线、Tick 通过下载 Parquet 切片后客户端解析(消耗流量);股票列表、交易日历、元数据走网关 JSON(不计流量)。
82
+ - **数据下载**:Parquet 文件下载或直读 DataFrame,计入订阅流量。
83
+ - **本地分析**:基于 DuckDB 对本地 Parquet 执行 SQL。
84
+ - **账户管理**:查询用户信息、用量、API Key、订阅与订单。
85
+ - **异步客户端**:基于 httpx,适用于 asyncio 量化框架。
86
+
87
+ ## 流量说明
88
+
89
+ 每月前 30 GB 下载流量免费,超出部分按 ¥1/GB 计费;账户余额不足时,下载会被限流,充值后即可恢复。
90
+
91
+ ## 文档
92
+
93
+ 完整文档请访问:https://www.quantmindai.cn/docs/sdk.html
@@ -0,0 +1,60 @@
1
+ # QuantDB Python SDK
2
+
3
+ QuantDB 量化数据平台官方 Python SDK,提供同步与异步两种客户端,封装了全部 API 端点。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install quantdb-sdk
9
+ ```
10
+
11
+ 开发依赖:
12
+
13
+ ```bash
14
+ pip install -e ".[dev]"
15
+ ```
16
+
17
+ ## 快速开始
18
+
19
+ ### API Key 鉴权(推荐)
20
+
21
+ ```python
22
+ from quantdb_sdk import QuantDBClient
23
+
24
+ client = QuantDBClient(api_key="qdb_xxx...")
25
+
26
+ # 查询用量
27
+ usage = client.get_usage()
28
+ print(f"已用: {usage['used_gb']:.2f} GB, 剩余: {usage['remaining_gb']:.2f} GB")
29
+
30
+ # K 线查询(免费)
31
+ df = client.query_kline(
32
+ "600519.SH",
33
+ adj_type="forward",
34
+ start_date="2026-01-01",
35
+ end_date="2026-07-22",
36
+ )
37
+ print(df.head())
38
+ ```
39
+
40
+ ### 用户名密码鉴权
41
+
42
+ ```python
43
+ client = QuantDBClient(username="admin", password="admin123")
44
+ ```
45
+
46
+ ## 核心功能
47
+
48
+ - **数据查询**:K 线、Tick 通过下载 Parquet 切片后客户端解析(消耗流量);股票列表、交易日历、元数据走网关 JSON(不计流量)。
49
+ - **数据下载**:Parquet 文件下载或直读 DataFrame,计入订阅流量。
50
+ - **本地分析**:基于 DuckDB 对本地 Parquet 执行 SQL。
51
+ - **账户管理**:查询用户信息、用量、API Key、订阅与订单。
52
+ - **异步客户端**:基于 httpx,适用于 asyncio 量化框架。
53
+
54
+ ## 流量说明
55
+
56
+ 每月前 30 GB 下载流量免费,超出部分按 ¥1/GB 计费;账户余额不足时,下载会被限流,充值后即可恢复。
57
+
58
+ ## 文档
59
+
60
+ 完整文档请访问:https://www.quantmindai.cn/docs/sdk.html
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "quantdb-sdk"
7
+ version = "0.1.0"
8
+ description = "QuantDB 量化数据平台官方 Python SDK"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.8"
12
+ authors = [
13
+ {name = "QuantDB Team"},
14
+ ]
15
+ keywords = ["quant", "finance", "data", "a-share", "parquet"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "Intended Audience :: Financial and Insurance Industry",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.8",
23
+ "Programming Language :: Python :: 3.9",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Topic :: Office/Business :: Financial",
28
+ ]
29
+ dependencies = [
30
+ "requests>=2.25.0",
31
+ "pandas>=1.3.0",
32
+ "httpx>=0.24.0",
33
+ "duckdb>=0.8.0",
34
+ ]
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "pytest>=7.0.0",
39
+ "pytest-asyncio>=0.21.0",
40
+ "responses>=0.23.0",
41
+ "respx>=0.20.0",
42
+ ]
43
+
44
+ [project.urls]
45
+ Homepage = "https://www.quantmindai.cn"
46
+ Documentation = "https://www.quantmindai.cn/docs/sdk.html"
47
+ Repository = "https://github.com/quantdb/quantdb"
48
+
49
+ [tool.setuptools.packages.find]
50
+ where = ["."]
51
+ include = ["quantdb_sdk*"]
@@ -0,0 +1,33 @@
1
+ """QuantDB 量化数据平台官方 Python SDK。"""
2
+
3
+ try:
4
+ from importlib.metadata import version
5
+ # 注意:此处用 PyPI 包名(连字符)查找版本号,不是模块名(下划线)
6
+ __version__ = version("quantdb-sdk")
7
+ except ImportError:
8
+ __version__ = "0.1.0"
9
+
10
+ from .async_client import AsyncQuantDBClient
11
+ from .client import DuckDBWarehouse, QuantDBClient
12
+ from .errors import (
13
+ AuthError,
14
+ InsufficientTrafficError,
15
+ NotFoundError,
16
+ QuantDBError,
17
+ RateLimitError,
18
+ ServerError,
19
+ ValidationError,
20
+ )
21
+
22
+ __all__ = [
23
+ "QuantDBClient",
24
+ "AsyncQuantDBClient",
25
+ "DuckDBWarehouse",
26
+ "QuantDBError",
27
+ "AuthError",
28
+ "InsufficientTrafficError",
29
+ "NotFoundError",
30
+ "RateLimitError",
31
+ "ServerError",
32
+ "ValidationError",
33
+ ]
@@ -0,0 +1,77 @@
1
+ """QuantDB SDK 命令行入口。
2
+
3
+ 提供快速验证和诊断功能:
4
+ python -m quantdb --version
5
+ python -m quantdb --help
6
+ python -m quantdb check <api_key> # 验证 API Key 是否有效
7
+ """
8
+
9
+ import argparse
10
+ import sys
11
+
12
+ from . import __version__
13
+ from .client import QuantDBClient
14
+
15
+
16
+ def main() -> int:
17
+ parser = argparse.ArgumentParser(
18
+ prog="quantdb",
19
+ description="QuantDB 量化数据平台官方 Python SDK",
20
+ )
21
+ parser.add_argument(
22
+ "--version",
23
+ action="version",
24
+ version=f"%(prog)s {__version__}",
25
+ )
26
+ parser.add_argument(
27
+ "--api-host",
28
+ default="https://quantdb.quantmind.cloud",
29
+ help="API 服务地址 (默认: https://quantdb.quantmind.cloud)",
30
+ )
31
+
32
+ subparsers = parser.add_subparsers(dest="command", help="可用命令")
33
+
34
+ # check 命令:验证 API Key
35
+ check_parser = subparsers.add_parser("check", help="验证 API Key 是否有效")
36
+ check_parser.add_argument("api_key", help="要验证的 API Key")
37
+
38
+ # usage 命令:查询用量
39
+ usage_parser = subparsers.add_parser("usage", help="查询账户用量和订阅状态")
40
+ usage_parser.add_argument("api_key", help="API Key")
41
+
42
+ args = parser.parse_args()
43
+
44
+ if not args.command:
45
+ parser.print_help()
46
+ return 0
47
+
48
+ try:
49
+ client = QuantDBClient(api_host=args.api_host, api_key=args.api_key)
50
+
51
+ if args.command == "check":
52
+ me = client.get_me()
53
+ print(f"✓ API Key 有效")
54
+ print(f" 用户: {me.get('username', 'N/A')}")
55
+ print(f" ID: {me.get('id', 'N/A')}")
56
+ return 0
57
+
58
+ if args.command == "usage":
59
+ usage = client.get_usage()
60
+ print(f"账户用量:")
61
+ print(f" 已用: {usage['used_gb']:.2f} GB")
62
+ print(f" 限额: {usage['limit_gb']:.1f} GB")
63
+ print(f" 剩余: {usage['remaining_gb']:.2f} GB")
64
+ print(f" 余额: ¥{usage['balance_yuan']:.2f}")
65
+ sub = usage.get("subscription", {})
66
+ print(f" 订阅: {sub.get('status', 'none')}")
67
+ return 0
68
+
69
+ except Exception as e:
70
+ print(f"✗ 错误: {e}", file=sys.stderr)
71
+ return 1
72
+
73
+ return 0
74
+
75
+
76
+ if __name__ == "__main__":
77
+ sys.exit(main())
@@ -0,0 +1,68 @@
1
+ """QuantDB SDK 内部工具函数。
2
+
3
+ 包含下载目录管理、文件名解析、字节换算等通用工具。
4
+ """
5
+
6
+ import os
7
+ import re
8
+ from urllib.parse import unquote
9
+
10
+
11
+ def default_download_dir() -> str:
12
+ """返回默认下载目录。
13
+
14
+ 优先读取环境变量 ``QUANTDB_DOWNLOAD_DIR``,未设置时按平台回退:
15
+
16
+ - Windows: ``D:\\QuantDB\\downloads\\``
17
+ - Linux/macOS: ``~/QuantDB/downloads/``
18
+
19
+ Returns:
20
+ 绝对路径字符串。
21
+ """
22
+ env = os.getenv("QUANTDB_DOWNLOAD_DIR")
23
+ if env:
24
+ return env.strip()
25
+ if os.name == "nt":
26
+ return r"D:\QuantDB\downloads"
27
+ return os.path.join(os.path.expanduser("~"), "QuantDB", "downloads")
28
+
29
+
30
+ def parse_filename_from_content_disposition(value: str, fallback: str) -> str:
31
+ """从 HTTP Content-Disposition 响应头解析文件名。
32
+
33
+ 支持 RFC 5987 (filename*=utf-8''name) 和常规 filename="name" 两种格式。
34
+ 解析失败时返回 *fallback*。
35
+
36
+ Args:
37
+ value: Content-Disposition 头的值。
38
+ fallback: 解析失败时的默认文件名。
39
+
40
+ Returns:
41
+ 解析后的文件名或 fallback。
42
+ """
43
+ if not value:
44
+ return fallback
45
+
46
+ # RFC 5987 filename*=utf-8''name
47
+ m = re.search(r"filename\*\s*=\s*(?:[^']*)'" r"(?:[^']*)'([^;]+)", value, re.IGNORECASE)
48
+ if m:
49
+ return unquote(m.group(1))
50
+
51
+ # filename="name" 或 filename=name
52
+ m = re.search(r'filename\s*=\s*"?([^";]+)"?', value, re.IGNORECASE)
53
+ if m:
54
+ return unquote(m.group(1).strip('"'))
55
+
56
+ return fallback
57
+
58
+
59
+ def bytes_to_gb(n: int) -> float:
60
+ """将字节数转换为 GB(1024 进制)。
61
+
62
+ Args:
63
+ n: 字节数。
64
+
65
+ Returns:
66
+ GB 数值(浮点数)。
67
+ """
68
+ return n / (1024 ** 3)