alpha-dc-client 0.3.1__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.
@@ -0,0 +1,486 @@
1
+ Metadata-Version: 2.5
2
+ Name: alpha-dc-client
3
+ Version: 0.3.1
4
+ Author-email: Hang GuangLiang <hanguangliang@alphaaidig.com>
5
+ Requires-Python: >=3.11
6
+ Requires-Dist: alpha-dc-common>=0.1.26
7
+ Requires-Dist: requests
8
+ Provides-Extra: parquet
9
+ Requires-Dist: duckdb>=0.10; extra == 'parquet'
10
+ Requires-Dist: pandas>=2.0; extra == 'parquet'
11
+ Requires-Dist: paramiko>=3.0; extra == 'parquet'
12
+ Requires-Dist: python-dotenv; extra == 'parquet'
13
+ Description-Content-Type: text/markdown
14
+
15
+ # DataCenter Client 使用指南
16
+
17
+ > 因子 Parquet 数据(本地镜像同步与读取)见 [DATA.md](DATA.md)。
18
+
19
+ ## 1. 🚀 安装
20
+
21
+ ```bash
22
+ pip install alpha-dc-client
23
+ ```
24
+
25
+ ## 1.5 🖥 命令行工具(CLI)
26
+
27
+ 安装后自带 `dcx` 命令(等价 `python -m dc_client.cli`),两条数据出口通道各一个命令面:
28
+
29
+ ```bash
30
+ # ── 认证(推荐一次性 login;环境变量优先级更高,CI/临时切换用)──
31
+ dcx login # 交互输入 Key(不回显),写 ~/.dc_data/auth.json
32
+ # export DC_API_KEY=<你的 API Key> # 环境变量方式(优先于 auth.json)
33
+ # export DC_API_URL=https://data.alphaaiming.com # 可选;本机调试用 --local
34
+ dcx whoami # 查看当前认证来源与目标(Key 打码)
35
+
36
+ # ── HTTP 通道:小表/维表/公告/快讯等(dc_api)──
37
+ dcx api list # 列出全部接口(服务端新 handler 自动出现)
38
+ dcx api list -k margin # 按关键字过滤
39
+ dcx api docs margin_analysis_list # 看单接口的参数与返回字段
40
+ dcx api query margin_analysis_list limit=50 # 通用查询(tushare query 风格)
41
+ dcx api query hsgt_fund_page_list stock_code=00700.HK --all # 自动翻页拉全
42
+ dcx api query margin_detail_page_list_by_stock stock_code=000001.SZ limit=100 \
43
+ -o detail.csv # 导出文件(csv/json/parquet 按扩展名推断)
44
+
45
+ # ── Parquet 通道:日线/因子宽表批量读(本地 duckdb,零网络)──
46
+ dcx data sync --market cn # 增量同步(首次 --full)
47
+ dcx data datasets # 看有哪些语义入口
48
+ dcx data load cn.stock_daily --start 2026-09-01 -o daily.parquet
49
+ dcx data load cn.market --columns trade_date,mkt_above_ma20_ratio # 跨层视图(columns 必填)
50
+ dcx data status # 新鲜度面板
51
+ ```
52
+
53
+ 分工纪律:**小查询用 `dcx api`;批量大数据量(全市场日线/因子)一定走 `dcx data`**——
54
+ HTTP 接口有分页/limit 上限,拉宽表又慢又挤服务端;本地 Parquet 读是并行 duckdb,秒级出全量。
55
+
56
+
57
+ ## 2. 🔑 认证设置
58
+
59
+ ### 获取API Token
60
+ 1. 联系管理员申请API Token
61
+ 2. 或者访问数据管理后台获取访问权限
62
+
63
+ ### 初始化客户端
64
+ ```python
65
+ import datacenter_client as dcx
66
+
67
+ # 基础初始化
68
+ client = dcx.init(
69
+ token='your_api_token_here'
70
+ )
71
+
72
+ # 使用环境变量
73
+ import os
74
+ client = dcx.init(token=os.getenv('DATACENTER_API_TOKEN'))
75
+ ```
76
+
77
+ ## 3. 🔍 查找需要的接口
78
+
79
+ ### 方法一:查看完整API列表
80
+ ```python
81
+ import requests
82
+
83
+ # 获取所有API
84
+ response = requests.get('http://data.alphaaidig.com/api/v1/docs/json')
85
+ if response.status_code == 200:
86
+ docs = response.json()
87
+ print(f"总共有 {docs['total_count']} 个API")
88
+ for api in docs['apis']:
89
+ print(f"- {api['name']}: {api['description']}")
90
+ ```
91
+
92
+ ### 方法二:搜索特定功能
93
+ ```python
94
+ # 搜索融资融券相关接口
95
+ response = requests.get('http://data.alphaaidig.com/api/v1/docs/search?q=margin')
96
+ if response.status_code == 200:
97
+ results = response.json()
98
+ for api in results['results']:
99
+ print(f"- {api['name']}: {api['description']}")
100
+ ```
101
+
102
+ ### 方法三:按类别查看
103
+ ```python
104
+ # 获取API分类
105
+ response = requests.get('http://data.alphaaidig.com/api/v1/docs/categories')
106
+ if response.status_code == 200:
107
+ categories = response.json()
108
+ print(f"API分类: {categories['categories']}")
109
+ ```
110
+
111
+ ## 4. 📋 访问接口
112
+
113
+ ### 基本调用方式
114
+ ```python
115
+ # 方式一:通过动态方法调用
116
+ result = client.hsgt_fund_page_list(page=1, page_size=20)
117
+
118
+ # 方式二:通过通用query方法
119
+ result = client.query('hsgt_fund_page_list', page=1, page_size=20)
120
+
121
+ # 方式三:指定返回字段
122
+ result = client.hsgt_fund_page_list(
123
+ page=1,
124
+ page_size=10,
125
+ fields='trade_date,stock_code,stock_name,hold_market_cap'
126
+ )
127
+ ```
128
+
129
+ ### 常用接口示例
130
+ ```python
131
+ # 沪深港通数据
132
+ df = client.hsgt_fund_page_list(page=1, page_size=20)
133
+ df = client.hsgt_north_fundxx()
134
+ df = client.hsgt_south_fundxx()
135
+
136
+ # A股数据
137
+ df = client.a_stock_page_list(page=1, page_size=20)
138
+ df = client.a_stock_list(limit=50)
139
+
140
+ # 港股数据
141
+ df = client.hk_stock_page_list(page=1, page_size=20)
142
+ df = client.hk_stock_list(limit=50)
143
+
144
+ # 行业数据
145
+ df = client.hs_industry_page_list(page=1, page_size=20)
146
+ df = client.hs_industry_company_page_list(page=1, page_size=20)
147
+ df = client.sw_industry_page_list(page=1, page_size=20)
148
+ df = client.sw_industry_company_page_list(page=1, page_size=20, level1_industry_code='801010.SI') # 指数码;数字码如 '110000' 亦可
149
+
150
+ # 融资融券数据
151
+ df = client.margin_account_page_list(page=1, page_size=20)
152
+ df = client.margin_account_list(limit=50)
153
+ df = client.margin_analysis_page_list(page=1, page_size=20)
154
+ df = client.margin_analysis_list(limit=50)
155
+ df = client.margin_detail_page_list_by_date(page=1, page_size=20)
156
+ df = client.margin_detail_page_list_by_stock(page=1, page_size=20)
157
+ df = client.margin_detail_list_by_stock(stock_code='000001.SZ', limit=50)
158
+ ```
159
+
160
+ ## 5. ❌ 错误处理
161
+
162
+ ```python
163
+ import datacenter_client as dcx
164
+ from datacenter_client.exceptions import (
165
+ DatacenterAPIError,
166
+ APIError,
167
+ AuthenticationError,
168
+ NotFoundError,
169
+ InvalidRequestError
170
+ )
171
+
172
+ def safe_api_call():
173
+ try:
174
+ client = dcx.init(token='your_api_token')
175
+ df = client.hsgt_fund_page_list(page=1, page_size=10)
176
+ return df
177
+
178
+ except AuthenticationError:
179
+ print("❌ 认证失败:请检查API token是否正确")
180
+ return None
181
+
182
+ except NotFoundError:
183
+ print("❌ API不存在:请检查API名称是否正确")
184
+ return None
185
+
186
+ except InvalidRequestError as e:
187
+ print(f"❌ 请求参数错误:{e}")
188
+ return None
189
+
190
+ except DatacenterAPIError as e:
191
+ print(f"❌ API错误:{e.message}")
192
+ return None
193
+
194
+ except Exception as e:
195
+ print(f"❌ 未知错误:{e}")
196
+ return None
197
+
198
+ # 使用
199
+ result = safe_api_call()
200
+ if result is not None:
201
+ print(f"✅ 成功获取 {len(result)} 条数据")
202
+ ```
203
+
204
+ ## 6. 📊 分页数据解析
205
+
206
+ ### 识别分页数据
207
+ ```python
208
+ import datacenter_client as dcx
209
+
210
+ client = dcx.init(token='your_api_token')
211
+
212
+ # 调用分页接口
213
+ result = client.hsgt_fund_page_list(page=1, page_size=20)
214
+
215
+ # 检查是否为分页数据
216
+ if hasattr(result, 'has_pagination') and result.has_pagination:
217
+ print("✅ 这是分页数据")
218
+ print(f"当前页: {result.current_page}")
219
+ print(f"每页大小: {result.page_size}")
220
+ print(f"总记录数: {result.total_count}")
221
+ print(f"总页数: {result.total_pages}")
222
+ else:
223
+ print("✅ 这是普通数据")
224
+ print(f"数据行数: {len(result)}")
225
+ ```
226
+
227
+ ### 遍历所有分页数据
228
+ ```python
229
+ def get_all_paginated_data(client, api_method, **kwargs):
230
+ """获取所有分页数据的通用函数"""
231
+ all_data = []
232
+ page = 1
233
+ page_size = 100 # 每页大小
234
+
235
+ while True:
236
+ try:
237
+ # 调用分页接口
238
+ result = api_method(page=page, page_size=page_size, **kwargs)
239
+
240
+ if hasattr(result, 'has_pagination') and result.has_pagination:
241
+ # 分页数据处理
242
+ all_data.extend(result.to_dict('records'))
243
+ print(f"✅ 第 {page} 页,累计 {len(all_data)} 条数据")
244
+
245
+ # 检查是否还有下一页
246
+ if page >= result.total_pages:
247
+ break
248
+ page += 1
249
+ else:
250
+ # 非分页数据
251
+ all_data.extend(result.to_dict('records'))
252
+ break
253
+
254
+ except Exception as e:
255
+ print(f"❌ 获取第 {page} 页数据失败:{e}")
256
+ break
257
+
258
+ return all_data
259
+
260
+ # 使用示例
261
+ client = dcx.init(token='your_api_token')
262
+ all_hsgt_data = get_all_paginated_data(
263
+ client,
264
+ client.hsgt_fund_page_list
265
+ )
266
+ print(f"总共获取 {len(all_hsgt_data)} 条数据")
267
+ ```
268
+
269
+ ## 7. 📄 非分页数据解析
270
+
271
+ ### 处理普通数据
272
+ ```python
273
+ import pandas as pd
274
+ import datacenter_client as dcx
275
+
276
+ client = dcx.init(token='your_api_token')
277
+
278
+ # 调用非分页接口
279
+ result = client.hsgt_north_fundxx()
280
+
281
+ # 检查数据类型
282
+ if isinstance(result, pd.DataFrame):
283
+ print(f"✅ 获取到DataFrame,共 {len(result)} 行")
284
+ print(f"列名: {list(result.columns)}")
285
+ print("前5行数据:")
286
+ print(result.head())
287
+ else:
288
+ print("✅ 获取到其他格式数据")
289
+ print(f"数据类型: {type(result)}")
290
+ print(f"数据内容: {result}")
291
+ ```
292
+
293
+ ### 指定返回字段
294
+ ```python
295
+ # 只获取需要的字段
296
+ result = client.hsgt_fund_page_list(
297
+ page=1,
298
+ page_size=10,
299
+ fields='trade_date,stock_code,stock_name,hold_market_cap'
300
+ )
301
+
302
+ print("返回的字段:", result.columns.tolist())
303
+ print("数据示例:")
304
+ print(result.head())
305
+ ```
306
+
307
+ ## 8. 🛠️ 高级用法
308
+
309
+ ### 配置化客户端
310
+ ```python
311
+ import os
312
+ from pathlib import Path
313
+ import json
314
+
315
+ class DataCenterConfig:
316
+ def __init__(self):
317
+ self.api_token = os.getenv('DATACENTER_API_TOKEN')
318
+ self.base_url = os.getenv('DATACENTER_BASE_URL', 'https://data.alphaaidig.com')
319
+ self.timeout = int(os.getenv('DATACENTER_TIMEOUT', '30'))
320
+
321
+ # 从配置文件读取
322
+ config_file = Path.home() / '.datacenter' / 'config.json'
323
+ if config_file.exists():
324
+ with open(config_file, 'r') as f:
325
+ config = json.load(f)
326
+ self.api_token = config.get('api_token', self.api_token)
327
+ self.base_url = config.get('base_url', self.base_url)
328
+ self.timeout = config.get('timeout', self.timeout)
329
+
330
+ def get_client(self):
331
+ if not self.api_token:
332
+ raise ValueError("❌ API Token未设置,请设置DATACENTER_API_TOKEN环境变量或配置文件")
333
+
334
+ return dcx.init(
335
+ token=self.api_token,
336
+ base_url=self.base_url,
337
+ timeout=self.timeout
338
+ )
339
+
340
+ # 使用
341
+ config = DataCenterConfig()
342
+ client = config.get_client()
343
+ ```
344
+
345
+ ### 批量查询
346
+ ```python
347
+ import pandas as pd
348
+ from typing import List
349
+ import time
350
+
351
+ def batch_query_stocks(stock_codes: List[str]) -> pd.DataFrame:
352
+ """批量查询多只股票数据"""
353
+ client = dcx.init(token='your_api_token')
354
+ all_data = []
355
+
356
+ for i, stock_code in enumerate(stock_codes):
357
+ try:
358
+ print(f"📊 查询股票 {stock_code} ({i+1}/{len(stock_codes)})")
359
+
360
+ # 这里可以根据需要调用不同的接口
361
+ result = client.a_stock_list(limit=1) # 示例调用
362
+
363
+ # 添加股票代码到结果中(如果接口没有返回)
364
+ if hasattr(result, 'to_dict'):
365
+ data_dict = result.to_dict()
366
+ if isinstance(data_dict, list):
367
+ all_data.extend(data_dict)
368
+ else:
369
+ all_data.append(data_dict)
370
+
371
+ # 添加延迟避免频率限制
372
+ time.sleep(0.1)
373
+
374
+ except Exception as e:
375
+ print(f"❌ 查询股票 {stock_code} 失败:{e}")
376
+ continue
377
+
378
+ if all_data:
379
+ return pd.DataFrame(all_data)
380
+ else:
381
+ return pd.DataFrame()
382
+
383
+ # 使用示例
384
+ stock_codes = ['000001', '000002', '600000', '600036']
385
+ df = batch_query_stocks(stock_codes)
386
+ print(f"总共获取 {len(df)} 条股票数据")
387
+ ```
388
+
389
+ ### 动态接口调用
390
+ ```python
391
+ def dynamic_api_call(client, api_name: str, **params):
392
+ """动态调用任意API接口"""
393
+ try:
394
+ # 方法一:通过动态属性调用
395
+ api_method = getattr(client, api_name)
396
+ result = api_method(**params)
397
+
398
+ # 方法二:通过query方法调用
399
+ # result = client.query(api_name, **params)
400
+
401
+ return result
402
+
403
+ except AttributeError:
404
+ print(f"❌ 接口 {api_name} 不存在")
405
+ return None
406
+ except Exception as e:
407
+ print(f"❌ 调用接口 {api_name} 失败:{e}")
408
+ return None
409
+
410
+ # 使用示例
411
+ client = dcx.init(token='your_api_token')
412
+ result = dynamic_api_call(client, 'hsgt_fund_page_list', page=1, page_size=10)
413
+ if result is not None:
414
+ print(f"成功获取 {len(result)} 条数据")
415
+ ```
416
+
417
+ ## 9. ❓ 常见问题
418
+
419
+ ### Q1: 如何获取API Token?
420
+ **A**: 请联系系统管理员或访问数据管理后台申请API访问权限。
421
+
422
+ ### Q2: 支持哪些股票代码格式?
423
+ **A**:
424
+ - A股:基础格式6位数字或带后缀格式,如 "000001", "600000","000001.SZ", "600000.SH"
425
+ - 港股:基础格式5位数字,如 "00700", "00941", "00700.HK"
426
+ - 指数:通常包含后缀,如 "000300.SH", "000905.SZ"
427
+
428
+ ### Q3: 如何知道某个接口是否存在?
429
+ **A**:
430
+ ```python
431
+ # 搜索接口
432
+ import requests
433
+ response = requests.get('http://data.alphaaidig.com/api/v1/docs/search?q=接口名')
434
+ if response.status_code == 200:
435
+ results = response.json()
436
+ print(f"找到 {results['total_count']} 个相关接口")
437
+ ```
438
+
439
+ ### Q4: 如何处理大量数据?
440
+ **A**:
441
+ 1. 每次请求适量数据
442
+ 2. 正确处理分页信息,避免遗漏数据
443
+ 3. 添加适当的延迟避免频率限制
444
+ 4. 使用批量处理提高效率
445
+
446
+ ### Q5: API调用失败怎么办?
447
+ **A**:
448
+ 1. 检查网络连接和base_url是否正确
449
+ 2. 验证API token是否有效
450
+ 3. 确认接口名称和参数是否正确
451
+ 4. 查看错误信息进行针对性处理
452
+ 5. 使用错误处理机制捕获异常
453
+
454
+ ### Q6: 返回的数据格式是什么?
455
+ **A**:
456
+ - **分页数据**: PageDataFrame,包含分页信息和数据
457
+ - **普通数据**: pandas DataFrame
458
+ - **单条记录**: pandas DataFrame(单行)
459
+ - **其他**: 根据具体接口可能返回不同格式
460
+
461
+ ### Q7: 如何获取完整的接口文档?
462
+ **A**:
463
+ ```python
464
+ import requests
465
+
466
+ # 获取完整文档
467
+ response = requests.get('http://data.alphaaidig.com/api/v1/docs/json')
468
+ if response.status_code == 200:
469
+ docs = response.json()
470
+ print(f"总共有 {docs['total_count']} 个接口")
471
+ for api in docs['apis']:
472
+ print(f"- {api['name']}: {api['description']}")
473
+ ```
474
+
475
+ ### Q8: IDE无法识别动态方法怎么办?
476
+ **A**: 现代IDE(如PyCharm、VSCode)会通过运行时学习动态方法,使用几次后就能识别。也可以:
477
+ 1. 使用 `client.query('方法名')` 的方式调用
478
+ 2. 添加类型提示注释
479
+ 3. 确保导入正确的异常类
480
+
481
+ ## 📞 技术支持
482
+
483
+ 如果遇到问题,可以:
484
+ 1. 查看API错误信息进行调试
485
+ 2. 访问 http://data.alphaaidig.com/api/v1/docs 查看完整API文档
486
+ 3. 联系技术支持团队
@@ -0,0 +1,22 @@
1
+ dc_client/__init__.py,sha256=A9DdQGudHtTfBU0AnLwQJ1NXyiJrbSgZx0FdaqOIJuU,350
2
+ dc_client/cli.py,sha256=TnIxjWSPGX9Z3Dyoj_PIR06HnD7su5rmVOlNDM_PVN4,16045
3
+ dc_client/client.py,sha256=U_Yc3I8IQl6rfK63DiXIBDUwfB9Daj4JFRTmVFl9xEc,11800
4
+ dc_client/client.pyi,sha256=MT8Ib4CrRF5q1wivk-2XaxkbiN8SO7JnoTKlGe_MdXU,2167
5
+ dc_client/exceptions.py,sha256=uxnjICHGOGdVJwt-tSwYJeSimOVpyh6R3_a0EqOw3iE,952
6
+ dc_client/ops_trader.py,sha256=F95yun79AgA2xfVem5peNdDAcgolMHnBvyvPx5gKy5I,12034
7
+ dc_client/output.py,sha256=Er9D8X_kj71UonXX7MtmR3KGBHkB-RIP5Zhp4vTuw9c,4495
8
+ dc_client/data/__init__.py,sha256=u_CXGsH1Qcn4vzbZkOOKYOgi9zujRPtw4dP5s61vhbc,2827
9
+ dc_client/data/__main__.py,sha256=MHKZ_ae3fSLGTLUUMOx15fWdeOnJSHhq-zslRP5F5Lc,79
10
+ dc_client/data/cli.py,sha256=Yhnwv6gSMv-vJPgMDiFXqtm2nH8hcIfEK33rTHboxxs,8915
11
+ dc_client/data/config.py,sha256=FwMp5R5UgfQAjG2mKiyeAXsElFcfew0BOxbPextzJ-c,3976
12
+ dc_client/data/discovery.py,sha256=rcie7-SRu3wmNYTRtG_uju5MQCU1LmBSjU2J9i-tnMo,12376
13
+ dc_client/data/io.py,sha256=6-hiTNHwJhSoQdH6gi9cTs5KZFxhdjdU4gA6tQm-oqw,27027
14
+ dc_client/data/namespace.py,sha256=KDTGuvcRhzIPkyZbdX_CMhOrU0iHxD1mbt6sgMDTr1c,7686
15
+ dc_client/data/registry.json,sha256=HXGXN97jBeEBDqhlf6OebasyGH91J726mvEG3vKMG74,133642
16
+ dc_client/data/registry.py,sha256=P7HFDoP7R-eu8Fmt3Gpo5AptwmsVG5OtQigbKW1q25c,3782
17
+ dc_client/data/remote.py,sha256=JHbSeO9XknfjcB_im2flJ7vz6qIyjPx-FOql0t0ELsI,12024
18
+ dc_client/data/sync.py,sha256=FVwV9WyLkYJ34dNXO1NqfiYE_WxY4r-VVaO_jjS8WAE,17696
19
+ alpha_dc_client-0.3.1.dist-info/METADATA,sha256=n5Cug3el04j60FA4lccYvULrGjr6uOU4Z6mAXMFu6fs,14900
20
+ alpha_dc_client-0.3.1.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
21
+ alpha_dc_client-0.3.1.dist-info/entry_points.txt,sha256=gQDe2Mt866EG4IaIkejRXC1DzgGfFYDdzVN1k0T4BTQ,43
22
+ alpha_dc_client-0.3.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dcx = dc_client.cli:main
dc_client/__init__.py ADDED
@@ -0,0 +1,13 @@
1
+ from .exceptions import APIError, AuthenticationError, NotFoundError, InvalidRequestError
2
+ from .client import DataApi, init, PageDataFrame, DatacenterAPIError
3
+
4
+ __all__ = [
5
+ "DataApi",
6
+ "init",
7
+ "PageDataFrame",
8
+ "DatacenterAPIError",
9
+ "APIError",
10
+ "AuthenticationError",
11
+ "NotFoundError",
12
+ "InvalidRequestError",
13
+ ]