litequant 3.0.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.
litequant/__init__.py ADDED
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # LiteQuant Client SDK
4
+ from .LiteQuantClient import DataTicket, LiteQuantClient
5
+
6
+ from .ParquetManager import ParquetDataManager
7
+ from .exceptions import (
8
+ LiteQuantError,
9
+ AuthError,
10
+ HostSelectionError,
11
+ RemoteDataError,
12
+ SerializationError,
13
+ LocalStorageError,
14
+ CategoryError,
15
+ CategoryNotFoundError,
16
+ InvalidCategoryError,
17
+ MetaError,
18
+ ProtocolError,
19
+ TicketExpiredError,
20
+ QuotaExceededError,
21
+ PermissionDeniedError,
22
+ NetworkError,
23
+ DataConnectionError,
24
+ ServiceUnavailableError,
25
+ SyncError,
26
+ APIError,
27
+ )
28
+
29
+ __version__ = "3.0.0"
30
+ __all__ = [
31
+ # Client
32
+ "LiteQuantClient",
33
+ "DataTicket",
34
+ "ParquetDataManager",
35
+ "LiteQuantError",
36
+ "AuthError",
37
+ "HostSelectionError",
38
+ "RemoteDataError",
39
+ "SerializationError",
40
+ "LocalStorageError",
41
+ "CategoryError",
42
+ "CategoryNotFoundError",
43
+ "InvalidCategoryError",
44
+ "MetaError",
45
+ "ProtocolError",
46
+ "TicketExpiredError",
47
+ "QuotaExceededError",
48
+ "PermissionDeniedError",
49
+ "NetworkError",
50
+ "DataConnectionError",
51
+ "ServiceUnavailableError",
52
+ "SyncError",
53
+ "APIError",
54
+ ]
@@ -0,0 +1,168 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ class LiteQuantError(Exception):
5
+ """Base SDK error with a public, privacy-safe message."""
6
+
7
+ code = "SERVICE_UNAVAILABLE"
8
+ user_message = "服务暂时不可用,请稍后重试"
9
+ retryable = False
10
+
11
+ def __init__(self, message=None, *, code=None, user_message=None, retryable=None, detail=None):
12
+ # Keep the public exception object privacy-safe. Internal implementation
13
+ # errors must not be attached here because users may print or inspect it.
14
+ self.detail = None
15
+ self.code = code or self.code
16
+ self.user_message = user_message or self.user_message
17
+ self.retryable = self.retryable if retryable is None else retryable
18
+ super().__init__(self.user_message)
19
+
20
+ def __str__(self):
21
+ return self.user_message
22
+
23
+ def __repr__(self):
24
+ return f"{self.__class__.__name__}(code={self.code!r}, user_message={self.user_message!r})"
25
+
26
+
27
+ class AuthError(LiteQuantError):
28
+ """Authentication failed."""
29
+
30
+ code = "AUTH_INVALID"
31
+ user_message = "API 凭证无效或已过期,请检查后重试"
32
+ retryable = False
33
+
34
+
35
+ class HostSelectionError(LiteQuantError):
36
+ """Host selection failed."""
37
+
38
+ code = "SERVICE_UNAVAILABLE"
39
+ user_message = "服务暂时不可用,请稍后重试"
40
+ retryable = True
41
+
42
+
43
+ class NetworkError(LiteQuantError):
44
+ """Network request failed."""
45
+
46
+ code = "CONNECTION_INTERRUPTED"
47
+ user_message = "连接中断,请检查网络后重试"
48
+ retryable = True
49
+
50
+
51
+ class DataConnectionError(LiteQuantError):
52
+ """Data connection failed."""
53
+
54
+ code = "CONNECTION_INTERRUPTED"
55
+ user_message = "连接中断,请重新初始化客户端"
56
+ retryable = True
57
+
58
+
59
+ class RemoteDataError(LiteQuantError):
60
+ """Remote data read failed."""
61
+
62
+ code = "DATA_UNAVAILABLE"
63
+ user_message = "数据暂时不可用,请稍后重试"
64
+ retryable = True
65
+
66
+
67
+ class SerializationError(LiteQuantError):
68
+ """Serialization or validation failed."""
69
+
70
+ code = "DATA_VERIFY_FAILED"
71
+ user_message = "数据校验失败,请重新同步"
72
+ retryable = True
73
+
74
+
75
+ class LocalStorageError(LiteQuantError):
76
+ """Local storage failed."""
77
+
78
+ code = "DATA_UNAVAILABLE"
79
+ user_message = "本地数据保存失败,请检查存储路径"
80
+ retryable = False
81
+
82
+
83
+ class CategoryError(LiteQuantError):
84
+ """Category related error."""
85
+
86
+ code = "DATA_UNAVAILABLE"
87
+ user_message = "数据类别不可用"
88
+ retryable = False
89
+
90
+
91
+ class CategoryNotFoundError(CategoryError):
92
+ """Category does not exist."""
93
+
94
+ code = "DATA_UNAVAILABLE"
95
+ user_message = "数据类别不存在或当前账号无权访问"
96
+ retryable = False
97
+
98
+
99
+ class InvalidCategoryError(CategoryError):
100
+ """Category name is invalid."""
101
+
102
+ code = "REQUEST_INVALID"
103
+ user_message = "数据类别名称无效"
104
+ retryable = False
105
+
106
+
107
+ class MetaError(LiteQuantError):
108
+ """Metadata error."""
109
+
110
+ code = "DATA_UNAVAILABLE"
111
+ user_message = "数据暂时不可用,请稍后重试"
112
+ retryable = True
113
+
114
+
115
+ class ProtocolError(LiteQuantError):
116
+ """Protocol mismatch."""
117
+
118
+ code = "SERVICE_UNAVAILABLE"
119
+ user_message = "服务暂时不可用,请升级客户端或稍后重试"
120
+ retryable = False
121
+
122
+
123
+ class TicketExpiredError(LiteQuantError):
124
+ """Connection credential expired."""
125
+
126
+ code = "CONNECTION_INTERRUPTED"
127
+ user_message = "连接已中断,请重新初始化客户端"
128
+ retryable = True
129
+
130
+
131
+ class QuotaExceededError(LiteQuantError):
132
+ """Quota or connection limit exceeded."""
133
+
134
+ code = "CONNECTION_LIMIT"
135
+ user_message = "连接数已达上限,请关闭其他连接后重试"
136
+ retryable = True
137
+
138
+
139
+ class PermissionDeniedError(LiteQuantError):
140
+ """Permission denied."""
141
+
142
+ code = "PERMISSION_DENIED"
143
+ user_message = "权限不足:当前账号没有该数据权限"
144
+ retryable = False
145
+
146
+
147
+ class ServiceUnavailableError(LiteQuantError):
148
+ """Service unavailable."""
149
+
150
+ code = "SERVICE_UNAVAILABLE"
151
+ user_message = "服务暂时不可用,请稍后重试"
152
+ retryable = True
153
+
154
+
155
+ class SyncError(LiteQuantError):
156
+ """One or more data sync tasks failed."""
157
+
158
+ code = "DATA_UNAVAILABLE"
159
+ user_message = "部分数据更新失败,请稍后重试"
160
+ retryable = True
161
+
162
+
163
+ class APIError(LiteQuantError):
164
+ """Generic API call failed."""
165
+
166
+ code = "SERVICE_UNAVAILABLE"
167
+ user_message = "服务暂时不可用,请稍后重试"
168
+ retryable = True
litequant/log.py ADDED
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import logging
4
+ import sys
5
+
6
+
7
+ def GetLogger(name: str = "litequant", level: int = logging.INFO) -> logging.Logger:
8
+ logger = logging.getLogger(name)
9
+
10
+ if logger.handlers:
11
+ logger.setLevel(level)
12
+ return logger
13
+
14
+ logger.setLevel(level)
15
+ logger.propagate = False
16
+
17
+ handler = logging.StreamHandler(sys.stdout)
18
+ formatter = logging.Formatter(
19
+ fmt="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
20
+ datefmt="%Y-%m-%d %H:%M:%S",
21
+ )
22
+ handler.setFormatter(formatter)
23
+ logger.addHandler(handler)
24
+ return logger
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LiteQuant
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.2
2
+ Name: litequant
3
+ Version: 3.0.0
4
+ Summary: LiteQuant Python client SDK
5
+ Author: LiteQuant Team
6
+ License: MIT
7
+ Project-URL: Homepage, https://litequant.com
8
+ Project-URL: Documentation, https://litequant.com/docs
9
+ Project-URL: Issues, https://litequant.com/support
10
+ Keywords: quant,finance,data,parquet,pandas
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Financial and Insurance Industry
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Office/Business :: Financial
23
+ Classifier: Topic :: Scientific/Engineering
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: pandas>=1.3.0
28
+ Requires-Dist: pyarrow>=10.0.0
29
+ Requires-Dist: redis>=4.0.0
30
+ Requires-Dist: requests>=2.25.0
31
+ Requires-Dist: tqdm>=4.60.0
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest<8.4,>=7.0; extra == "test"
34
+ Provides-Extra: release
35
+ Requires-Dist: build>=1.0; extra == "release"
36
+ Requires-Dist: twine>=5.0; extra == "release"
37
+ Provides-Extra: dev
38
+ Requires-Dist: pytest<8.4,>=7.0; extra == "dev"
39
+ Requires-Dist: build>=1.0; extra == "dev"
40
+ Requires-Dist: twine>=5.0; extra == "dev"
41
+
42
+ # LiteQuant Python SDK
43
+
44
+ LiteQuant Python SDK 用于在本地下载和读取 LiteQuant 数据。SDK 会自动处理连接、同步、本地 Parquet 缓存和常见错误提示。
45
+
46
+ 支持 Python 3.8 及以上版本。
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install litequant
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ ```python
57
+ from litequant import LiteQuantClient
58
+
59
+ client = LiteQuantClient(
60
+ api_token="your_api_token",
61
+ save_path="./litequant_data",
62
+ )
63
+
64
+ client.UpdateAllCategory(update_method="incremental")
65
+ df = client.GetCategory("cn_stock_pivot#open")
66
+ print(df.tail())
67
+
68
+ client.close()
69
+ ```
70
+
71
+ 推荐使用上下文管理器自动关闭连接:
72
+
73
+ ```python
74
+ from litequant import LiteQuantClient
75
+
76
+ with LiteQuantClient(api_token="your_api_token", save_path="./litequant_data") as client:
77
+ categories = client.ListCategories()
78
+ df = client.GetCategory(categories[0])
79
+ ```
80
+
81
+ 默认 API 地址为 `https://www.litequant.pro`。如需连接测试环境,可以传入 `api_url` 或设置环境变量 `LITEQUANT_API_URL`。
82
+
83
+ ## Error Handling
84
+
85
+ SDK 默认会在 Python 终端输出功能面错误提示,同时抛出类型化异常。错误信息不会展示后端细节。
86
+
87
+ ```python
88
+ from litequant import LiteQuantClient, LiteQuantError
89
+
90
+ try:
91
+ with LiteQuantClient(api_token="your_api_token", save_path="./litequant_data") as client:
92
+ df = client.GetCategory("cn_stock_pivot#open")
93
+ except LiteQuantError as exc:
94
+ print(exc.code)
95
+ print(exc.user_message)
96
+ print(exc.retryable)
97
+ ```
98
+
99
+ 如果你希望完全自己处理错误提示,可以关闭终端输出:
100
+
101
+ ```python
102
+ client = LiteQuantClient(
103
+ api_token="your_api_token",
104
+ save_path="./litequant_data",
105
+ display_errors=False,
106
+ )
107
+ ```
108
+
109
+ 常见公开错误码:
110
+
111
+ - `AUTH_INVALID`:API 凭证无效或已过期
112
+ - `ACCOUNT_UNAVAILABLE`:账号不可用
113
+ - `SUBSCRIPTION_UNAVAILABLE`:套餐不可用或已过期
114
+ - `PERMISSION_DENIED`:权限不足
115
+ - `CONNECTION_LIMIT`:连接数已达上限
116
+ - `CONNECTION_INTERRUPTED`:连接已中断,请重新连接
117
+ - `REQUEST_INVALID`:请求参数无效
118
+ - `SERVICE_UNAVAILABLE`:服务暂时不可用
119
+ - `DATA_UNAVAILABLE`:数据暂时不可用
120
+ - `DATA_VERIFY_FAILED`:数据校验失败
121
+
122
+ ## Data Cache
123
+
124
+ SDK 会把数据保存为本地 Parquet 缓存。再次读取同一数据类别时,会优先使用本地缓存;如果本地没有该数据类别,SDK 会自动同步。
125
+
126
+ 当前 pivot 数据支持 `monthly` 和 `daily` 两种分区模式。后续可以在服务端元信息和客户端缓存层一起扩展更多分区模式。
127
+
128
+ ## Metadata Contract
129
+
130
+ 数据服务会提供客户端可识别的类别列表、类别元信息和分区元信息。客户端会自动读取这些元信息并完成数据同步。
131
+
132
+ 公开稳定字段包括:
133
+
134
+ - `partition_mode`:pivot 分区模式,目前支持 `monthly` 和 `daily`
135
+ - `partition_keys`:数据分区标识列表
136
+ - `hash`:数据校验值
137
+ - `key_columns` / `dedupe_keys`:unstack 数据去重键
138
+
139
+ 普通用户通常不需要直接使用这些字段。
@@ -0,0 +1,10 @@
1
+ litequant/LiteQuantClient.py,sha256=6rob4I0a8sohfoeG68xwoQnXbUECwmaA-eoE10KtZRc,33397
2
+ litequant/ParquetManager.py,sha256=eYoq-veV8DH7RjZHaTBxHWhAJ-B4UV6dnrGIoSIfRuM,55694
3
+ litequant/__init__.py,sha256=7TkrmgWx97ndsIdz8cvy_rcpoiBmgONzBgRfxY64Ca8,1208
4
+ litequant/exceptions.py,sha256=p93kxzaPvP_vQ_p9XsITxzOwANcLUbRbgyJayPa9T84,4428
5
+ litequant/log.py,sha256=dRE9oXTyyNoGBpU67Suaz4mITzZXtuRpkp188qEeUWQ,612
6
+ litequant-3.0.0.dist-info/LICENSE,sha256=v4ndfeoLXVjQaijygqdq6QPTg9iS3RKofG1EKNRhUZg,1066
7
+ litequant-3.0.0.dist-info/METADATA,sha256=MDirJTDKALBKEol1co6Pqz4teX3BOn7kBEYRwQ-QvHg,4687
8
+ litequant-3.0.0.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
9
+ litequant-3.0.0.dist-info/top_level.txt,sha256=ktSowtaruI9jxc1qPpgwBQjR0UvDgDEf15s92HqCzLw,10
10
+ litequant-3.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (76.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ litequant