quantdb-sdk 0.4.3__tar.gz → 0.4.4__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.
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/CHANGELOG.md +16 -0
- {quantdb_sdk-0.4.3/quantdb_sdk.egg-info → quantdb_sdk-0.4.4}/PKG-INFO +1 -1
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/pyproject.toml +1 -1
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/__init__.py +1 -1
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/__main__.py +6 -3
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/async_client.py +38 -3
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/client.py +54 -4
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/examples/demo_01_connect_basics.py +6 -1
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4/quantdb_sdk.egg-info}/PKG-INFO +1 -1
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/LICENSE +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/MANIFEST.in +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/README.md +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/_utils.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/errors.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/examples/__init__.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/examples/demo_02_kline_v2_daily.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/examples/demo_03_sync_full_market.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/examples/demo_04_duckdb_warehouse.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/examples/demo_05_read_local_data.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/examples/demo_06_tick_and_factors.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/examples/demo_07_data_hub.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/hub.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/layout.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk/py.typed +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk.egg-info/SOURCES.txt +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk.egg-info/dependency_links.txt +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk.egg-info/entry_points.txt +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk.egg-info/requires.txt +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/quantdb_sdk.egg-info/top_level.txt +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/setup.cfg +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/tests/test_async_client.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/tests/test_client.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/tests/test_data_hub.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/tests/test_hub_models.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/tests/test_layout.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/tests/test_technical_indicators.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/tests/test_update_pipeline.py +0 -0
- {quantdb_sdk-0.4.3 → quantdb_sdk-0.4.4}/tests/test_utils.py +0 -0
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
所有 notable 变更都会记录在此文件。格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
4
4
|
版本号遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/)。
|
|
5
5
|
|
|
6
|
+
## \[0.4.4] - 2026-10-11
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **`get_usage()` / `a_get_usage()` 漏算流量包额度**:旧实现用 `remaining = traffic_limit + credit_limit + purchased_traffic - used_traffic`,**完全没算流量包**,导致持有流量包的用户剩余流量被低估(少报的量正好等于流量包余额),`is_active` 也会在仍有流量包可用时被误判为 `False`。
|
|
11
|
+
|
|
12
|
+
修正后的口径与后端下载预扣一致:可用总额度 = 套餐额度(`traffic_limit + credit_limit + purchased_traffic`)+ 流量包总额;可用剩余 = (套餐额度 − 已用) + 流量包剩余。因用量接口返回的 `package_traffic` 是流量包**剩余量**,总额从 `GET /api/v1/subscription/traffic-packages` 台账累加;台账接口不可用时退化为「总额 = 剩余」,保证 `get_usage()` 在旧版服务端上依然可用。
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`get_usage()` / `a_get_usage()` 新增额度明细字段**(原有字段全部保留,取值已修正):
|
|
17
|
+
- 合计:`total_gb` / `used_gb` / `remaining_gb`
|
|
18
|
+
- 套餐额度:`plan_total_gb` / `plan_used_gb` / `plan_remaining_gb`
|
|
19
|
+
- 流量包额度:`package_total_gb` / `package_used_gb` / `package_remaining_gb`
|
|
20
|
+
- **`quantdb usage` CLI** 改为分行展示套餐 / 流量包 / 合计的已用、总额与剩余,不再只显示一个总额。
|
|
21
|
+
|
|
6
22
|
## \[0.4.3] - 2026-10-05
|
|
7
23
|
|
|
8
24
|
### Changed
|
|
@@ -135,9 +135,12 @@ def main() -> int:
|
|
|
135
135
|
if args.command == "usage":
|
|
136
136
|
usage = client.get_usage()
|
|
137
137
|
print(f"账户用量:")
|
|
138
|
-
print(f"
|
|
139
|
-
|
|
140
|
-
print(f"
|
|
138
|
+
print(f" 套餐: 已用 {usage['plan_used_gb']:.2f} GB / {usage['plan_total_gb']:.2f} GB"
|
|
139
|
+
f"(剩余 {usage['plan_remaining_gb']:.2f} GB)")
|
|
140
|
+
print(f" 流量包: 已用 {usage['package_used_gb']:.2f} GB / {usage['package_total_gb']:.2f} GB"
|
|
141
|
+
f"(剩余 {usage['package_remaining_gb']:.2f} GB)")
|
|
142
|
+
print(f" 合计: 已用 {usage['used_gb']:.2f} GB / {usage['total_gb']:.2f} GB"
|
|
143
|
+
f"(剩余 {usage['remaining_gb']:.2f} GB)")
|
|
141
144
|
print(f" 余额: ¥{usage['balance_yuan']:.2f}")
|
|
142
145
|
sub = usage.get("subscription", {})
|
|
143
146
|
print(f" 订阅: {sub.get('status', 'none')}")
|
|
@@ -28,7 +28,7 @@ from .errors import (
|
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
# 维护提示:每次发版必须与 pyproject.toml 版本号同步
|
|
31
|
-
_USER_AGENT = "QuantDB-Python-SDK/0.4.
|
|
31
|
+
_USER_AGENT = "QuantDB-Python-SDK/0.4.4"
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
def _etag_hex(value: Optional[str]) -> Optional[str]:
|
|
@@ -287,21 +287,56 @@ class AsyncQuantDBClient:
|
|
|
287
287
|
return await self._get("/api/v1/auth/me")
|
|
288
288
|
|
|
289
289
|
async def a_get_usage(self) -> Dict[str, Any]:
|
|
290
|
+
"""获取当前账户流量与订阅使用情况(异步版,字段含义见 ``QuantDBClient.get_usage``)。"""
|
|
290
291
|
data = await self._get("/api/v1/auth/usage")
|
|
291
292
|
used = data.get("used_traffic", 0)
|
|
292
293
|
limit = data.get("traffic_limit", 0)
|
|
293
294
|
credit = data.get("credit_limit", 0)
|
|
294
295
|
purchased = data.get("purchased_traffic", 0)
|
|
296
|
+
package_remaining = data.get("package_traffic", 0)
|
|
295
297
|
subscription = data.get("subscription", {}) or {}
|
|
298
|
+
|
|
299
|
+
plan_total = limit + credit + purchased
|
|
300
|
+
plan_remaining = max(0, plan_total - used)
|
|
301
|
+
|
|
302
|
+
# 流量包总额只能从台账取(用量接口只给剩余量)。台账接口不可用时退化为
|
|
303
|
+
# 「总额 = 剩余」,保证 a_get_usage 在旧版服务端上依然可用。
|
|
304
|
+
package_total = package_remaining
|
|
305
|
+
try:
|
|
306
|
+
ledger = await self._get("/api/v1/subscription/traffic-packages")
|
|
307
|
+
active = [
|
|
308
|
+
p for p in (ledger.get("packages") or [])
|
|
309
|
+
if str(p.get("status", "")).lower() == "active"
|
|
310
|
+
]
|
|
311
|
+
if active:
|
|
312
|
+
package_total = sum(int(p.get("quota_bytes") or 0) for p in active)
|
|
313
|
+
except QuantDBError:
|
|
314
|
+
pass
|
|
315
|
+
|
|
316
|
+
package_used = max(0, package_total - package_remaining)
|
|
317
|
+
total = plan_total + package_total
|
|
318
|
+
remaining = plan_remaining + package_remaining
|
|
319
|
+
|
|
296
320
|
return {
|
|
321
|
+
# 合计
|
|
322
|
+
"total_gb": bytes_to_gb(total),
|
|
297
323
|
"used_gb": bytes_to_gb(used),
|
|
324
|
+
"remaining_gb": bytes_to_gb(remaining),
|
|
325
|
+
# 套餐额度(月度重置)
|
|
326
|
+
"plan_total_gb": bytes_to_gb(plan_total),
|
|
327
|
+
"plan_used_gb": bytes_to_gb(used),
|
|
328
|
+
"plan_remaining_gb": bytes_to_gb(plan_remaining),
|
|
329
|
+
# 流量包额度(一年有效、可叠加)
|
|
330
|
+
"package_total_gb": bytes_to_gb(package_total),
|
|
331
|
+
"package_used_gb": bytes_to_gb(package_used),
|
|
332
|
+
"package_remaining_gb": bytes_to_gb(package_remaining),
|
|
333
|
+
# 兼容旧字段
|
|
298
334
|
"limit_gb": bytes_to_gb(limit),
|
|
299
335
|
"credit_gb": bytes_to_gb(credit),
|
|
300
336
|
"purchased_gb": bytes_to_gb(purchased),
|
|
301
|
-
"remaining_gb": max(0.0, bytes_to_gb(limit + credit + purchased - used)),
|
|
302
337
|
"balance_yuan": data.get("balance_yuan", 0.0),
|
|
303
338
|
"subscription": subscription,
|
|
304
|
-
"is_active": subscription.get("status") == "active" and
|
|
339
|
+
"is_active": subscription.get("status") == "active" and remaining > 0,
|
|
305
340
|
}
|
|
306
341
|
|
|
307
342
|
async def a_register(self, username: str, email: str, password: str) -> Dict[str, Any]:
|
|
@@ -32,7 +32,7 @@ from .errors import (
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
# 维护提示:每次发版必须与 pyproject.toml 版本号同步
|
|
35
|
-
_USER_AGENT = "QuantDB-Python-SDK/0.4.
|
|
35
|
+
_USER_AGENT = "QuantDB-Python-SDK/0.4.4"
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def _etag_hex(value: Optional[str]) -> Optional[str]:
|
|
@@ -325,22 +325,72 @@ class QuantDBClient:
|
|
|
325
325
|
return self._get("/api/v1/auth/me")
|
|
326
326
|
|
|
327
327
|
def get_usage(self) -> Dict[str, Any]:
|
|
328
|
-
"""获取当前账户流量与订阅使用情况。
|
|
328
|
+
"""获取当前账户流量与订阅使用情况。
|
|
329
|
+
|
|
330
|
+
额度模型(与后端下载预扣逻辑一致):
|
|
331
|
+
|
|
332
|
+
- **套餐额度**(月度重置):``traffic_limit + credit_limit + purchased_traffic``,
|
|
333
|
+
下载时优先从该额度池扣减,已用量即 ``used_traffic``;
|
|
334
|
+
- **流量包额度**(一年有效、可叠加):台账 ``traffic_packages``。
|
|
335
|
+
接口返回的 ``package_traffic`` 是流量包**剩余量**,总额需从台账累加。
|
|
336
|
+
|
|
337
|
+
因此:可用总额度 = 套餐额度 + 流量包总额;
|
|
338
|
+
可用剩余 = (套餐额度 - 已用) + 流量包剩余。
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
用量字典,包含合计(``total_gb``/``used_gb``/``remaining_gb``)、
|
|
342
|
+
套餐额度(``plan_*``)、流量包额度(``package_*``)三组字段,
|
|
343
|
+
以及兼容旧版的 ``limit_gb``/``credit_gb``/``purchased_gb``。
|
|
344
|
+
"""
|
|
329
345
|
data = self._get("/api/v1/auth/usage")
|
|
330
346
|
used = data.get("used_traffic", 0)
|
|
331
347
|
limit = data.get("traffic_limit", 0)
|
|
332
348
|
credit = data.get("credit_limit", 0)
|
|
333
349
|
purchased = data.get("purchased_traffic", 0)
|
|
350
|
+
package_remaining = data.get("package_traffic", 0)
|
|
334
351
|
subscription = data.get("subscription", {}) or {}
|
|
352
|
+
|
|
353
|
+
plan_total = limit + credit + purchased
|
|
354
|
+
plan_remaining = max(0, plan_total - used)
|
|
355
|
+
|
|
356
|
+
# 流量包总额只能从台账取(用量接口只给剩余量)。台账接口不可用时退化为
|
|
357
|
+
# 「总额 = 剩余」,保证 get_usage 在旧版服务端上依然可用。
|
|
358
|
+
package_total = package_remaining
|
|
359
|
+
try:
|
|
360
|
+
ledger = self._get("/api/v1/subscription/traffic-packages")
|
|
361
|
+
active = [
|
|
362
|
+
p for p in (ledger.get("packages") or [])
|
|
363
|
+
if str(p.get("status", "")).lower() == "active"
|
|
364
|
+
]
|
|
365
|
+
if active:
|
|
366
|
+
package_total = sum(int(p.get("quota_bytes") or 0) for p in active)
|
|
367
|
+
except QuantDBError:
|
|
368
|
+
pass
|
|
369
|
+
|
|
370
|
+
package_used = max(0, package_total - package_remaining)
|
|
371
|
+
total = plan_total + package_total
|
|
372
|
+
remaining = plan_remaining + package_remaining
|
|
373
|
+
|
|
335
374
|
return {
|
|
375
|
+
# 合计
|
|
376
|
+
"total_gb": bytes_to_gb(total),
|
|
336
377
|
"used_gb": bytes_to_gb(used),
|
|
378
|
+
"remaining_gb": bytes_to_gb(remaining),
|
|
379
|
+
# 套餐额度(月度重置)
|
|
380
|
+
"plan_total_gb": bytes_to_gb(plan_total),
|
|
381
|
+
"plan_used_gb": bytes_to_gb(used),
|
|
382
|
+
"plan_remaining_gb": bytes_to_gb(plan_remaining),
|
|
383
|
+
# 流量包额度(一年有效、可叠加)
|
|
384
|
+
"package_total_gb": bytes_to_gb(package_total),
|
|
385
|
+
"package_used_gb": bytes_to_gb(package_used),
|
|
386
|
+
"package_remaining_gb": bytes_to_gb(package_remaining),
|
|
387
|
+
# 兼容旧字段
|
|
337
388
|
"limit_gb": bytes_to_gb(limit),
|
|
338
389
|
"credit_gb": bytes_to_gb(credit),
|
|
339
390
|
"purchased_gb": bytes_to_gb(purchased),
|
|
340
|
-
"remaining_gb": max(0.0, bytes_to_gb(limit + credit + purchased - used)),
|
|
341
391
|
"balance_yuan": data.get("balance_yuan", 0.0),
|
|
342
392
|
"subscription": subscription,
|
|
343
|
-
"is_active": subscription.get("status") == "active" and
|
|
393
|
+
"is_active": subscription.get("status") == "active" and remaining > 0,
|
|
344
394
|
}
|
|
345
395
|
|
|
346
396
|
def register(self, username: str, email: str, password: str) -> Dict[str, Any]:
|
|
@@ -30,7 +30,12 @@ def main() -> None:
|
|
|
30
30
|
print("账户:", me.get("username"), "| ID:", me.get("id"))
|
|
31
31
|
|
|
32
32
|
usage = client.get_usage()
|
|
33
|
-
print(f"
|
|
33
|
+
print(f"套餐: 已用 {usage['plan_used_gb']:.2f} GB / {usage['plan_total_gb']:.2f} GB"
|
|
34
|
+
f" / 剩余 {usage['plan_remaining_gb']:.2f} GB")
|
|
35
|
+
print(f"流量包: 已用 {usage['package_used_gb']:.2f} GB / {usage['package_total_gb']:.2f} GB"
|
|
36
|
+
f" / 剩余 {usage['package_remaining_gb']:.2f} GB")
|
|
37
|
+
print(f"合计: 已用 {usage['used_gb']:.2f} GB / {usage['total_gb']:.2f} GB"
|
|
38
|
+
f" / 剩余 {usage['remaining_gb']:.2f} GB")
|
|
34
39
|
print("订阅:", usage.get("subscription", {}).get("status", "none"))
|
|
35
40
|
|
|
36
41
|
stocks = client.query_stock_list(keyword=args.keyword, limit=5)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|