qdata-quote 0.3.2__tar.gz → 0.3.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.
Files changed (20) hide show
  1. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/PKG-INFO +18 -8
  2. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/README.md +17 -7
  3. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/pyproject.toml +1 -1
  4. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/service.py +15 -3
  5. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/tests/test_service.py +25 -1
  6. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/uv.lock +1 -1
  7. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/.gitignore +0 -0
  8. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/docs/superpowers/plans/2026-06-12-quote-service.md +0 -0
  9. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/docs/superpowers/specs/2026-06-12-quote-service-design.md +0 -0
  10. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/__init__.py +0 -0
  11. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/bench.py +0 -0
  12. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/sources/__init__.py +0 -0
  13. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/sources/base.py +0 -0
  14. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/sources/sina.py +0 -0
  15. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/sources/tencent.py +0 -0
  16. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/stock_codes.py +0 -0
  17. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/src/qdata_quote/types.py +0 -0
  18. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/tests/test_sina.py +0 -0
  19. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/tests/test_tencent.py +0 -0
  20. {qdata_quote-0.3.2 → qdata_quote-0.3.4}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qdata-quote
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: 实时行情采集服务,支持新浪和腾讯数据源
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.10
@@ -25,13 +25,10 @@ pip install qdata-quote
25
25
  ## 快速开始
26
26
 
27
27
  ```python
28
- from qdata_quote import QuoteService, get_stock_codes
29
-
30
- # 获取全市场股票代码(首次从网络获取约 4 秒,后续读缓存 <1ms)
31
- codes = get_stock_codes()
28
+ from qdata_quote import QuoteService
32
29
 
30
+ # 默认加载全市场股票列表(初始化时自动从网络刷新)
33
31
  service = QuoteService()
34
- service.set_stock_codes(codes)
35
32
 
36
33
  # 同步获取指定股票行情
37
34
  df = service.get_real_sync(["000001", "600000"])
@@ -46,6 +43,21 @@ df = asyncio.run(service.get_real(["000001", "600000"]))
46
43
  df_all = asyncio.run(service.get_all())
47
44
  ```
48
45
 
46
+ ## 自定义股票列表
47
+
48
+ ```python
49
+ from qdata_quote import QuoteService
50
+
51
+ # 传入自定义股票列表(不会自动刷新)
52
+ service = QuoteService(codes=["000001", "600000", "300750"])
53
+
54
+ # 随时替换股票列表(切换为自定义模式,不再接受 refresh)
55
+ service.set_stock_codes(["000001", "600000"])
56
+
57
+ # 刷新全市场股票列表(仅在使用默认列表时生效)
58
+ service.refresh_stock_codes()
59
+ ```
60
+
49
61
  ## 获取股票代码
50
62
 
51
63
  ```python
@@ -124,12 +136,10 @@ df = service.get_real_sync(["000001"], source="tencent")
124
136
  ```python
125
137
  # 同步
126
138
  with QuoteService() as service:
127
- service.set_stock_codes(get_stock_codes())
128
139
  df = service.get_all_sync()
129
140
 
130
141
  # 异步
131
142
  async with QuoteService() as service:
132
- service.set_stock_codes(get_stock_codes())
133
143
  df = await service.get_all()
134
144
  ```
135
145
 
@@ -11,13 +11,10 @@ pip install qdata-quote
11
11
  ## 快速开始
12
12
 
13
13
  ```python
14
- from qdata_quote import QuoteService, get_stock_codes
15
-
16
- # 获取全市场股票代码(首次从网络获取约 4 秒,后续读缓存 <1ms)
17
- codes = get_stock_codes()
14
+ from qdata_quote import QuoteService
18
15
 
16
+ # 默认加载全市场股票列表(初始化时自动从网络刷新)
19
17
  service = QuoteService()
20
- service.set_stock_codes(codes)
21
18
 
22
19
  # 同步获取指定股票行情
23
20
  df = service.get_real_sync(["000001", "600000"])
@@ -32,6 +29,21 @@ df = asyncio.run(service.get_real(["000001", "600000"]))
32
29
  df_all = asyncio.run(service.get_all())
33
30
  ```
34
31
 
32
+ ## 自定义股票列表
33
+
34
+ ```python
35
+ from qdata_quote import QuoteService
36
+
37
+ # 传入自定义股票列表(不会自动刷新)
38
+ service = QuoteService(codes=["000001", "600000", "300750"])
39
+
40
+ # 随时替换股票列表(切换为自定义模式,不再接受 refresh)
41
+ service.set_stock_codes(["000001", "600000"])
42
+
43
+ # 刷新全市场股票列表(仅在使用默认列表时生效)
44
+ service.refresh_stock_codes()
45
+ ```
46
+
35
47
  ## 获取股票代码
36
48
 
37
49
  ```python
@@ -110,12 +122,10 @@ df = service.get_real_sync(["000001"], source="tencent")
110
122
  ```python
111
123
  # 同步
112
124
  with QuoteService() as service:
113
- service.set_stock_codes(get_stock_codes())
114
125
  df = service.get_all_sync()
115
126
 
116
127
  # 异步
117
128
  async with QuoteService() as service:
118
- service.set_stock_codes(get_stock_codes())
119
129
  df = await service.get_all()
120
130
  ```
121
131
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "qdata-quote"
7
- version = "0.3.2"
7
+ version = "0.3.4"
8
8
  description = "实时行情采集服务,支持新浪和腾讯数据源"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -32,7 +32,12 @@ class QuoteService:
32
32
  """
33
33
 
34
34
  def __init__(self, codes: list[str] | None = None):
35
- self._stock_codes: list[str] = codes if codes is not None else get_stock_codes()
35
+ # 标记是否使用自定义列表:自定义列表时 refresh 不覆盖
36
+ self._use_default_codes = codes is None
37
+ if self._use_default_codes:
38
+ self._stock_codes = get_stock_codes(refresh=True)
39
+ else:
40
+ self._stock_codes = codes
36
41
  self._sources = {
37
42
  "sina": SinaSource(),
38
43
  "tencent": TencentSource(),
@@ -42,11 +47,18 @@ class QuoteService:
42
47
  self._default_source: SourceName = "sina"
43
48
 
44
49
  def set_stock_codes(self, codes: list[str]) -> None:
45
- """替换股票代码列表"""
50
+ """替换股票代码列表(切换为自定义模式,不再接受 refresh)"""
51
+ self._use_default_codes = False
46
52
  self._stock_codes = codes
47
53
 
48
54
  def refresh_stock_codes(self) -> None:
49
- """从网络刷新全市场股票代码列表并更新"""
55
+ """从网络刷新全市场股票代码列表
56
+
57
+ 仅在使用默认列表时生效;通过构造方法或 set_stock_codes
58
+ 指定了自定义列表后,调用此方法不做任何操作。
59
+ """
60
+ if not self._use_default_codes:
61
+ return
50
62
  self._stock_codes = get_stock_codes(refresh=True)
51
63
 
52
64
  # --- 异步接口(aiohttp) ---
@@ -30,11 +30,35 @@ class TestQuoteServiceInit:
30
30
  assert s._stock_codes == []
31
31
 
32
32
 
33
- class TestSetStockCodes:
33
+ class TestStockCodesManagement:
34
34
  def test_set_codes(self, service):
35
35
  service.set_stock_codes(["000001", "600000"])
36
36
  assert service._stock_codes == ["000001", "600000"]
37
37
 
38
+ def test_refresh_with_default_codes(self, service):
39
+ """默认模式下 refresh 可以刷新"""
40
+ assert service._use_default_codes is True
41
+ old = service._stock_codes[:]
42
+ service.refresh_stock_codes()
43
+ # 刷新后列表不为空(即使内容相同)
44
+ assert len(service._stock_codes) > 0
45
+
46
+ def test_refresh_with_custom_codes_no_op(self):
47
+ """自定义模式下 refresh 不覆盖"""
48
+ s = QuoteService(codes=["000001", "600000"])
49
+ assert s._use_default_codes is False
50
+ s.refresh_stock_codes()
51
+ # 列表保持不变,没有被覆盖为全市场列表
52
+ assert s._stock_codes == ["000001", "600000"]
53
+
54
+ def test_set_codes_disables_refresh(self, service):
55
+ """set_stock_codes 切换为自定义模式"""
56
+ assert service._use_default_codes is True
57
+ service.set_stock_codes(["000001"])
58
+ assert service._use_default_codes is False
59
+ service.refresh_stock_codes()
60
+ assert service._stock_codes == ["000001"]
61
+
38
62
 
39
63
  class TestQuoteServiceSync:
40
64
  """同步接口集成测试(需要网络)"""
@@ -1103,7 +1103,7 @@ wheels = [
1103
1103
 
1104
1104
  [[package]]
1105
1105
  name = "qdata-quote"
1106
- version = "0.3.1"
1106
+ version = "0.3.2"
1107
1107
  source = { editable = "." }
1108
1108
  dependencies = [
1109
1109
  { name = "aiohttp" },
File without changes