zerone-cli 0.1.8__tar.gz → 0.3.1__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 (50) hide show
  1. zerone_cli-0.3.1/PKG-INFO +187 -0
  2. zerone_cli-0.3.1/README.md +160 -0
  3. zerone_cli-0.3.1/cli/client.py +173 -0
  4. zerone_cli-0.3.1/cli/commands/__init__.py +23 -0
  5. zerone_cli-0.3.1/cli/commands/execute_aggregate_query.py +73 -0
  6. zerone_cli-0.3.1/cli/commands/execute_query.py +81 -0
  7. zerone_cli-0.3.1/cli/commands/get_available_tables.py +28 -0
  8. zerone_cli-0.3.1/cli/commands/get_table_schema.py +30 -0
  9. zerone_cli-0.3.1/cli/main.py +38 -0
  10. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/pyproject.toml +1 -1
  11. zerone_cli-0.3.1/zerone_cli.egg-info/PKG-INFO +187 -0
  12. zerone_cli-0.3.1/zerone_cli.egg-info/SOURCES.txt +26 -0
  13. zerone_cli-0.1.8/PKG-INFO +0 -169
  14. zerone_cli-0.1.8/README.md +0 -142
  15. zerone_cli-0.1.8/cli/client.py +0 -422
  16. zerone_cli-0.1.8/cli/commands/__init__.py +0 -19
  17. zerone_cli-0.1.8/cli/commands/basic_info.py +0 -77
  18. zerone_cli-0.1.8/cli/commands/entity_exit_list.py +0 -47
  19. zerone_cli-0.1.8/cli/commands/entity_invest_list.py +0 -47
  20. zerone_cli-0.1.8/cli/commands/entity_managed_funds_list.py +0 -42
  21. zerone_cli-0.1.8/cli/commands/evt_company_financing.py +0 -48
  22. zerone_cli-0.1.8/cli/commands/evt_company_ipo.py +0 -48
  23. zerone_cli-0.1.8/cli/commands/evt_company_repurchase.py +0 -48
  24. zerone_cli-0.1.8/cli/commands/evt_company_secondary.py +0 -48
  25. zerone_cli-0.1.8/cli/commands/evt_listing_company_reduction.py +0 -48
  26. zerone_cli-0.1.8/cli/commands/evt_listing_company_unlock.py +0 -48
  27. zerone_cli-0.1.8/cli/commands/evt_lp_investment.py +0 -46
  28. zerone_cli-0.1.8/cli/commands/evt_ma_company_deal.py +0 -48
  29. zerone_cli-0.1.8/cli/commands/evt_s_fund_deal.py +0 -46
  30. zerone_cli-0.1.8/cli/commands/financing.py +0 -84
  31. zerone_cli-0.1.8/cli/commands/shareholders.py +0 -88
  32. zerone_cli-0.1.8/cli/main.py +0 -49
  33. zerone_cli-0.1.8/zerone_cli.egg-info/PKG-INFO +0 -169
  34. zerone_cli-0.1.8/zerone_cli.egg-info/SOURCES.txt +0 -37
  35. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/__init__.py +0 -0
  36. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/commands/config_cmd.py +0 -0
  37. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/commands/entity_financial_list.py +0 -0
  38. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/commands/entity_profile.py +0 -0
  39. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/commands/entity_search.py +0 -0
  40. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/commands/model_company_match_gp.py +0 -0
  41. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/commands/model_financing_probability.py +0 -0
  42. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/config.py +0 -0
  43. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/utils/__init__.py +0 -0
  44. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/utils/errors.py +0 -0
  45. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/cli/utils/output.py +0 -0
  46. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/setup.cfg +0 -0
  47. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/zerone_cli.egg-info/dependency_links.txt +0 -0
  48. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/zerone_cli.egg-info/entry_points.txt +0 -0
  49. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/zerone_cli.egg-info/requires.txt +0 -0
  50. {zerone_cli-0.1.8 → zerone_cli-0.3.1}/zerone_cli.egg-info/top_level.txt +0 -0
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.4
2
+ Name: zerone-cli
3
+ Version: 0.3.1
4
+ Summary: Zerone 私募股权数据 CLI 工具
5
+ Author-email: Zerone <tech@zerone.com.cn>
6
+ License: MIT
7
+ Project-URL: Homepage, https://ai.zerone.com.cn
8
+ Project-URL: Documentation, https://ai.zerone.com.cn
9
+ Keywords: cli,private-equity,finance,mcp,zerone
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Environment :: Console
17
+ Classifier: Intended Audience :: Financial and Insurance Industry
18
+ Classifier: Topic :: Office/Business :: Financial
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: typer>=0.9.0
22
+ Requires-Dist: httpx>=0.24.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Requires-Dist: pyyaml>=6.0
25
+ Requires-Dist: rich>=13.0.0
26
+ Requires-Dist: pandas>=2.0.0
27
+
28
+ # Zerone CLI
29
+
30
+ Zerone 私募股权数据命令行工具,通过 API Key 直接查询 Zerone 数据平台。
31
+
32
+ ## 安装
33
+
34
+ ```bash
35
+ pip install zerone-cli
36
+ ```
37
+
38
+ ## 快速开始
39
+
40
+ ### 1. 配置 API Key
41
+
42
+ ```bash
43
+ zerone config set-api-key YOUR_API_KEY
44
+ ```
45
+
46
+ > 如何获取 API Key?请访问 [https://ai.zerone.com.cn](https://ai.zerone.com.cn) 注册账号后申请。
47
+
48
+ ### 2. 查看帮助
49
+
50
+ ```bash
51
+ zerone --help
52
+ ```
53
+
54
+ ### 3. 开始查询
55
+
56
+ #### 第一层:实体定位
57
+
58
+ ```bash
59
+ # 实体模糊搜索
60
+ zerone entity-search "字节跳动"
61
+ ```
62
+
63
+ #### 第二层:业务专题
64
+
65
+ ```bash
66
+ # 查询实体综合画像
67
+ zerone entity-profile "中国石油"
68
+
69
+ # 查询实体财务数据列表
70
+ zerone entity-financial-list "中国石油" --page 1 --page-size 50
71
+
72
+ # 查询融资概率预测
73
+ zerone model-financing-probability "字节跳动" --type COMPANY
74
+
75
+ # 查询机构匹配推荐
76
+ zerone model-company-match-gp "字节跳动" --page 1 --page-size 5
77
+ ```
78
+
79
+ #### 第三层:通用数据查询
80
+
81
+ ```bash
82
+ # 查看有哪些表可以查
83
+ zerone get-available-tables
84
+
85
+ # 查看某张表的结构(字段名、类型、支持的操作符)
86
+ zerone get-table-schema company
87
+
88
+ # 单表查询(通过 JSON 文件传入参数)
89
+ zerone query --json-file query.json
90
+
91
+ # 聚合查询(通过 JSON 文件传入参数)
92
+ zerone aggregate --json-file aggregate.json
93
+ ```
94
+
95
+ ## 命令列表
96
+
97
+ | 命令 | 说明 | 层级 |
98
+ |------|------|------|
99
+ | `zerone config set-api-key` | 设置 API Key | — |
100
+ | `zerone config set-server-url` | 设置服务器地址(可选) | — |
101
+ | `zerone config show` | 查看当前配置 | — |
102
+ | `zerone entity-search` | 实体模糊搜索 | 第一层 |
103
+ | `zerone entity-profile` | 查询实体综合画像 | 第二层 |
104
+ | `zerone entity-financial-list` | 查询实体财务数据列表(分页) | 第二层 |
105
+ | `zerone model-financing-probability` | 查询融资概率预测模型 | 第二层 |
106
+ | `zerone model-company-match-gp` | 为项目公司匹配潜在投资机构 | 第二层 |
107
+ | `zerone get-available-tables` | 获取可查询表列表 | 第三层 |
108
+ | `zerone get-table-schema` | 获取指定表结构 | 第三层 |
109
+ | `zerone query` | 单表查询(筛选/排序/分页) | 第三层 |
110
+ | `zerone aggregate` | 聚合查询(GROUP BY + 聚合函数) | 第三层 |
111
+
112
+ ## 通用查询 JSON 参数示例
113
+
114
+ ### query.json(单表查询)
115
+
116
+ ```json
117
+ {
118
+ "table": "company",
119
+ "select_columns": ["company_name", "found_date", "vertical"],
120
+ "filters": [
121
+ {"field": "vertical", "type": "like", "value": "人工智能"},
122
+ {"field": "found_date", "type": "range", "value": ["2020-01-01", "2024-12-31"]}
123
+ ],
124
+ "order_by": ["found_date DESC"],
125
+ "limit": 50
126
+ }
127
+ ```
128
+
129
+ ### aggregate.json(聚合查询)
130
+
131
+ ```json
132
+ {
133
+ "table": "company",
134
+ "group_by": ["reg_province"],
135
+ "metrics": [
136
+ {"field": "company_id", "func": "count", "alias": "company_count"}
137
+ ],
138
+ "filters": [
139
+ {"field": "vertical", "type": "like", "value": "人工智能"}
140
+ ],
141
+ "order_by": ["company_count DESC"],
142
+ "limit": 50
143
+ }
144
+ ```
145
+
146
+ ### 使用方式
147
+
148
+ ```bash
149
+ # 从文件读取参数
150
+ zerone query --json-file query.json
151
+ zerone aggregate --json-file aggregate.json
152
+
153
+ # 直接传入 JSON 字符串
154
+ zerone query --json '{"table":"company","select_columns":["company_name"],"limit":10}'
155
+ zerone aggregate --json '{"table":"company","group_by":["reg_province"],"metrics":[{"field":"company_id","func":"count","alias":"cnt"}]}'
156
+ ```
157
+
158
+ ## 常用参数说明
159
+
160
+ ### 分页参数
161
+ - `--page`: 页码,从1开始,默认1
162
+ - `--page-size`: 每页条数,默认50,上限50
163
+
164
+ ### 输出格式
165
+ - `--output`: 输出格式,可选 table/json/csv,默认 table
166
+
167
+ ### 查询参数
168
+ - `--json-file`: JSON 参数文件路径(query/aggregate 专用)
169
+ - `--json`: JSON 参数字符串(query/aggregate 专用)
170
+
171
+ ## 配置说明
172
+
173
+ 配置文件保存在 `~/.zerone/config.yaml`,支持以下环境变量覆盖:
174
+
175
+ | 环境变量 | 说明 |
176
+ |----------|------|
177
+ | `ZERONE_API_KEY` | API Key |
178
+ | `ZERONE_SERVER_URL` | 服务器地址 |
179
+
180
+ ## 系统要求
181
+
182
+ - Python 3.9+
183
+ - 有效的 Zerone API Key
184
+
185
+ ## 许可证
186
+
187
+ MIT
@@ -0,0 +1,160 @@
1
+ # Zerone CLI
2
+
3
+ Zerone 私募股权数据命令行工具,通过 API Key 直接查询 Zerone 数据平台。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install zerone-cli
9
+ ```
10
+
11
+ ## 快速开始
12
+
13
+ ### 1. 配置 API Key
14
+
15
+ ```bash
16
+ zerone config set-api-key YOUR_API_KEY
17
+ ```
18
+
19
+ > 如何获取 API Key?请访问 [https://ai.zerone.com.cn](https://ai.zerone.com.cn) 注册账号后申请。
20
+
21
+ ### 2. 查看帮助
22
+
23
+ ```bash
24
+ zerone --help
25
+ ```
26
+
27
+ ### 3. 开始查询
28
+
29
+ #### 第一层:实体定位
30
+
31
+ ```bash
32
+ # 实体模糊搜索
33
+ zerone entity-search "字节跳动"
34
+ ```
35
+
36
+ #### 第二层:业务专题
37
+
38
+ ```bash
39
+ # 查询实体综合画像
40
+ zerone entity-profile "中国石油"
41
+
42
+ # 查询实体财务数据列表
43
+ zerone entity-financial-list "中国石油" --page 1 --page-size 50
44
+
45
+ # 查询融资概率预测
46
+ zerone model-financing-probability "字节跳动" --type COMPANY
47
+
48
+ # 查询机构匹配推荐
49
+ zerone model-company-match-gp "字节跳动" --page 1 --page-size 5
50
+ ```
51
+
52
+ #### 第三层:通用数据查询
53
+
54
+ ```bash
55
+ # 查看有哪些表可以查
56
+ zerone get-available-tables
57
+
58
+ # 查看某张表的结构(字段名、类型、支持的操作符)
59
+ zerone get-table-schema company
60
+
61
+ # 单表查询(通过 JSON 文件传入参数)
62
+ zerone query --json-file query.json
63
+
64
+ # 聚合查询(通过 JSON 文件传入参数)
65
+ zerone aggregate --json-file aggregate.json
66
+ ```
67
+
68
+ ## 命令列表
69
+
70
+ | 命令 | 说明 | 层级 |
71
+ |------|------|------|
72
+ | `zerone config set-api-key` | 设置 API Key | — |
73
+ | `zerone config set-server-url` | 设置服务器地址(可选) | — |
74
+ | `zerone config show` | 查看当前配置 | — |
75
+ | `zerone entity-search` | 实体模糊搜索 | 第一层 |
76
+ | `zerone entity-profile` | 查询实体综合画像 | 第二层 |
77
+ | `zerone entity-financial-list` | 查询实体财务数据列表(分页) | 第二层 |
78
+ | `zerone model-financing-probability` | 查询融资概率预测模型 | 第二层 |
79
+ | `zerone model-company-match-gp` | 为项目公司匹配潜在投资机构 | 第二层 |
80
+ | `zerone get-available-tables` | 获取可查询表列表 | 第三层 |
81
+ | `zerone get-table-schema` | 获取指定表结构 | 第三层 |
82
+ | `zerone query` | 单表查询(筛选/排序/分页) | 第三层 |
83
+ | `zerone aggregate` | 聚合查询(GROUP BY + 聚合函数) | 第三层 |
84
+
85
+ ## 通用查询 JSON 参数示例
86
+
87
+ ### query.json(单表查询)
88
+
89
+ ```json
90
+ {
91
+ "table": "company",
92
+ "select_columns": ["company_name", "found_date", "vertical"],
93
+ "filters": [
94
+ {"field": "vertical", "type": "like", "value": "人工智能"},
95
+ {"field": "found_date", "type": "range", "value": ["2020-01-01", "2024-12-31"]}
96
+ ],
97
+ "order_by": ["found_date DESC"],
98
+ "limit": 50
99
+ }
100
+ ```
101
+
102
+ ### aggregate.json(聚合查询)
103
+
104
+ ```json
105
+ {
106
+ "table": "company",
107
+ "group_by": ["reg_province"],
108
+ "metrics": [
109
+ {"field": "company_id", "func": "count", "alias": "company_count"}
110
+ ],
111
+ "filters": [
112
+ {"field": "vertical", "type": "like", "value": "人工智能"}
113
+ ],
114
+ "order_by": ["company_count DESC"],
115
+ "limit": 50
116
+ }
117
+ ```
118
+
119
+ ### 使用方式
120
+
121
+ ```bash
122
+ # 从文件读取参数
123
+ zerone query --json-file query.json
124
+ zerone aggregate --json-file aggregate.json
125
+
126
+ # 直接传入 JSON 字符串
127
+ zerone query --json '{"table":"company","select_columns":["company_name"],"limit":10}'
128
+ zerone aggregate --json '{"table":"company","group_by":["reg_province"],"metrics":[{"field":"company_id","func":"count","alias":"cnt"}]}'
129
+ ```
130
+
131
+ ## 常用参数说明
132
+
133
+ ### 分页参数
134
+ - `--page`: 页码,从1开始,默认1
135
+ - `--page-size`: 每页条数,默认50,上限50
136
+
137
+ ### 输出格式
138
+ - `--output`: 输出格式,可选 table/json/csv,默认 table
139
+
140
+ ### 查询参数
141
+ - `--json-file`: JSON 参数文件路径(query/aggregate 专用)
142
+ - `--json`: JSON 参数字符串(query/aggregate 专用)
143
+
144
+ ## 配置说明
145
+
146
+ 配置文件保存在 `~/.zerone/config.yaml`,支持以下环境变量覆盖:
147
+
148
+ | 环境变量 | 说明 |
149
+ |----------|------|
150
+ | `ZERONE_API_KEY` | API Key |
151
+ | `ZERONE_SERVER_URL` | 服务器地址 |
152
+
153
+ ## 系统要求
154
+
155
+ - Python 3.9+
156
+ - 有效的 Zerone API Key
157
+
158
+ ## 许可证
159
+
160
+ MIT
@@ -0,0 +1,173 @@
1
+ from typing import Any, Optional
2
+
3
+ import httpx
4
+
5
+ from cli.config import config_manager
6
+
7
+
8
+ class MCPClient:
9
+
10
+ def __init__(self):
11
+ self.api_key = config_manager.get_api_key()
12
+ self.server_url = config_manager.get_server_url()
13
+ self.client = httpx.Client(timeout=60.0)
14
+
15
+ def _request(
16
+ self,
17
+ method: str,
18
+ path: str,
19
+ json_data: Optional[dict] = None,
20
+ params: Optional[dict] = None,
21
+ ) -> dict:
22
+ url = f"{self.server_url}{path}"
23
+ headers = {
24
+ "Authorization": f"Bearer {self.api_key}",
25
+ "Content-Type": "application/json",
26
+ }
27
+
28
+ try:
29
+ response = self.client.request(
30
+ method=method,
31
+ url=url,
32
+ headers=headers,
33
+ json=json_data,
34
+ params=params,
35
+ )
36
+ response.raise_for_status()
37
+ data = response.json()
38
+ if not data.get("success", True):
39
+ error = data.get("error", {})
40
+ raise ValueError(f"[{error.get('code', 'UNKNOWN')}] {error.get('message', '未知错误')}")
41
+ return data
42
+ except httpx.HTTPStatusError as e:
43
+ try:
44
+ error_data = e.response.json()
45
+ detail = error_data.get("detail", "")
46
+ if detail:
47
+ raise ValueError(f"[HTTP {e.response.status_code}] {detail}")
48
+ except ValueError:
49
+ raise
50
+ except Exception:
51
+ pass
52
+ raise ValueError(f"请求失败: {e.response.status_code} - {e.response.text}")
53
+ except httpx.ConnectError:
54
+ raise ValueError(f"无法连接到 MCP Server,请检查 server_url 配置:{self.server_url}")
55
+ except httpx.TimeoutException:
56
+ raise ValueError("请求超时,请检查网络连接或稍后重试")
57
+
58
+ # ========== 第一层:实体定位 ==========
59
+
60
+ def entity_search(self, keyword: str) -> dict:
61
+ return self._request(
62
+ "POST",
63
+ "/rest-api/tool/entity_search",
64
+ json_data={"keyword": keyword},
65
+ )
66
+
67
+ # ========== 第二层:业务专题 ==========
68
+
69
+ def entity_profile(
70
+ self,
71
+ entity_name: str,
72
+ entity_type: Optional[str] = None,
73
+ ) -> dict:
74
+ return self._request(
75
+ "POST",
76
+ "/rest-api/tool/entity_profile",
77
+ json_data={
78
+ "entity_name": entity_name,
79
+ "entity_type": entity_type or "",
80
+ },
81
+ )
82
+
83
+ def entity_financial_list(
84
+ self,
85
+ entity_name: str,
86
+ entity_type: Optional[str] = None,
87
+ page: int = 1,
88
+ page_size: int = 50,
89
+ ) -> dict:
90
+ return self._request(
91
+ "POST",
92
+ "/rest-api/tool/entity_financial_list",
93
+ json_data={
94
+ "entity_name": entity_name,
95
+ "entity_type": entity_type or "",
96
+ "page": page,
97
+ "page_size": page_size,
98
+ },
99
+ )
100
+
101
+ def model_financing_probability(
102
+ self,
103
+ entity_name: str,
104
+ entity_type: Optional[str] = None,
105
+ ) -> dict:
106
+ return self._request(
107
+ "POST",
108
+ "/rest-api/tool/model_financing_probability",
109
+ json_data={
110
+ "entity_name": entity_name,
111
+ "entity_type": entity_type or "",
112
+ },
113
+ )
114
+
115
+ def model_company_match_gp(
116
+ self,
117
+ company_name: str,
118
+ page: int = 1,
119
+ page_size: int = 5,
120
+ ) -> dict:
121
+ return self._request(
122
+ "POST",
123
+ "/rest-api/tool/model_company_match_gp",
124
+ json_data={
125
+ "company_name": company_name,
126
+ "page": page,
127
+ "page_size": page_size,
128
+ },
129
+ )
130
+
131
+ # ========== 第三层:通用数据查询 ==========
132
+
133
+ def get_available_tables(self) -> dict:
134
+ return self._request("POST", "/rest-api/tool/get_available_tables")
135
+
136
+ def get_table_schema(self, table_name: str) -> dict:
137
+ return self._request(
138
+ "POST",
139
+ "/rest-api/tool/get_table_schema",
140
+ json_data={"table_name": table_name},
141
+ )
142
+
143
+ def execute_query(self, payload: dict) -> dict:
144
+ return self._request(
145
+ "POST",
146
+ "/rest-api/tool/execute_query",
147
+ json_data=payload,
148
+ )
149
+
150
+ def execute_aggregate_query(self, payload: dict) -> dict:
151
+ return self._request(
152
+ "POST",
153
+ "/rest-api/tool/execute_aggregate_query",
154
+ json_data=payload,
155
+ )
156
+
157
+ # ========== Debug ==========
158
+
159
+ def debug_preview_sql(self, payload: dict) -> dict:
160
+ return self._request(
161
+ "POST",
162
+ "/debug/preview-sql",
163
+ json_data=payload,
164
+ )
165
+
166
+ def close(self):
167
+ self.client.close()
168
+
169
+ def __enter__(self):
170
+ return self
171
+
172
+ def __exit__(self, exc_type, exc_val, exc_tb):
173
+ self.close()
@@ -0,0 +1,23 @@
1
+ from cli.commands import config_cmd
2
+ from cli.commands.entity_search import entity_search
3
+ from cli.commands.entity_profile import entity_profile
4
+ from cli.commands.entity_financial_list import entity_financial_list
5
+ from cli.commands.model_financing_probability import model_financing_probability
6
+ from cli.commands.model_company_match_gp import model_company_match_gp
7
+ from cli.commands.get_available_tables import get_available_tables
8
+ from cli.commands.get_table_schema import get_table_schema
9
+ from cli.commands.execute_query import execute_query
10
+ from cli.commands.execute_aggregate_query import execute_aggregate_query
11
+
12
+ __all__ = [
13
+ "config_cmd",
14
+ "entity_search",
15
+ "entity_profile",
16
+ "entity_financial_list",
17
+ "model_financing_probability",
18
+ "model_company_match_gp",
19
+ "get_available_tables",
20
+ "get_table_schema",
21
+ "execute_query",
22
+ "execute_aggregate_query",
23
+ ]
@@ -0,0 +1,73 @@
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Optional
4
+
5
+ import typer
6
+
7
+ from cli.client import MCPClient
8
+ from cli.utils.output import print_result
9
+
10
+
11
+ def execute_aggregate_query(
12
+ json_file: Optional[str] = typer.Option(
13
+ None, "--json-file", "-f",
14
+ help="JSON 参数文件路径,内含 table/group_by/metrics/filters/order_by/limit"
15
+ ),
16
+ json_string: Optional[str] = typer.Option(
17
+ None, "--json", "-j",
18
+ help="JSON 参数字符串"
19
+ ),
20
+ output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
21
+ ):
22
+ """
23
+ 通用聚合查询
24
+
25
+ 支持 GROUP BY + 聚合函数(sum/avg/max/min/count/count_distinct)。
26
+ 参数较复杂,必须通过 JSON 文件或 JSON 字符串传入。
27
+
28
+ JSON 参数示例:
29
+ {
30
+ "table": "company",
31
+ "group_by": ["reg_province"],
32
+ "metrics": [
33
+ {"field": "company_id", "func": "count", "alias": "company_count"}
34
+ ],
35
+ "filters": [
36
+ {"field": "vertical", "type": "like", "value": "人工智能"}
37
+ ],
38
+ "order_by": ["company_count DESC"],
39
+ "limit": 50
40
+ }
41
+
42
+ 示例:
43
+ zerone aggregate --json-file aggregate.json
44
+ zerone aggregate --json '{"table":"company","group_by":["reg_province"],"metrics":[{"field":"company_id","func":"count","alias":"cnt"}]}'
45
+ """
46
+ payload = None
47
+
48
+ if json_file:
49
+ path = Path(json_file)
50
+ if not path.exists():
51
+ typer.echo(f"错误: 文件不存在 {json_file}", err=True)
52
+ raise typer.Exit(1)
53
+ payload = json.loads(path.read_text(encoding="utf-8"))
54
+ elif json_string:
55
+ payload = json.loads(json_string)
56
+ else:
57
+ typer.echo(
58
+ "错误: 必须提供 --json-file 或 --json 参数。\n"
59
+ "使用 --help 查看 JSON 参数格式示例。",
60
+ err=True,
61
+ )
62
+ raise typer.Exit(1)
63
+
64
+ try:
65
+ with MCPClient() as client:
66
+ result = client.execute_aggregate_query(payload)
67
+ print_result(result, output)
68
+ except ValueError as e:
69
+ typer.echo(f"错误: {e}", err=True)
70
+ raise typer.Exit(1)
71
+ except Exception as e:
72
+ typer.echo(f"请求失败: {e}", err=True)
73
+ raise typer.Exit(1)
@@ -0,0 +1,81 @@
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Optional
4
+
5
+ import typer
6
+
7
+ from cli.client import MCPClient
8
+ from cli.utils.output import print_result
9
+
10
+
11
+ def execute_query(
12
+ json_file: Optional[str] = typer.Option(
13
+ None, "--json-file", "-f",
14
+ help="JSON 参数文件路径,内含 table/select_columns/filters/order_by/limit"
15
+ ),
16
+ json_string: Optional[str] = typer.Option(
17
+ None, "--json", "-j",
18
+ help="JSON 参数字符串,如 '{\"table\":\"company\",\"select_columns\":[\"company_name\"],\"limit\":10}'"
19
+ ),
20
+ table: Optional[str] = typer.Option(
21
+ None, "--table", "-t",
22
+ help="表名(与 --json-file/--json 互斥时使用)"
23
+ ),
24
+ limit: int = typer.Option(
25
+ 200, "--limit", "-l",
26
+ help="返回条数上限"
27
+ ),
28
+ output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
29
+ ):
30
+ """
31
+ 通用单表查询
32
+
33
+ 支持筛选、排序、分页。参数较复杂,推荐通过 JSON 文件传入。
34
+
35
+ JSON 参数示例:
36
+ {
37
+ "table": "company",
38
+ "select_columns": ["company_name", "found_date", "vertical"],
39
+ "filters": [
40
+ {"field": "vertical", "type": "like", "value": "人工智能"},
41
+ {"field": "found_date", "type": "range", "value": ["2020-01-01", "2024-12-31"]}
42
+ ],
43
+ "order_by": ["found_date DESC"],
44
+ "limit": 50
45
+ }
46
+
47
+ 示例:
48
+ zerone query --json-file query.json
49
+ zerone query --json '{"table":"company","select_columns":["company_name"],"limit":10}'
50
+ zerone query --table company --limit 10
51
+ """
52
+ payload = None
53
+
54
+ if json_file:
55
+ path = Path(json_file)
56
+ if not path.exists():
57
+ typer.echo(f"错误: 文件不存在 {json_file}", err=True)
58
+ raise typer.Exit(1)
59
+ payload = json.loads(path.read_text(encoding="utf-8"))
60
+ elif json_string:
61
+ payload = json.loads(json_string)
62
+ elif table:
63
+ payload = {"table": table, "select_columns": [], "limit": limit}
64
+ else:
65
+ typer.echo(
66
+ "错误: 必须提供 --json-file、--json 或 --table 参数。\n"
67
+ "使用 --help 查看 JSON 参数格式示例。",
68
+ err=True,
69
+ )
70
+ raise typer.Exit(1)
71
+
72
+ try:
73
+ with MCPClient() as client:
74
+ result = client.execute_query(payload)
75
+ print_result(result, output)
76
+ except ValueError as e:
77
+ typer.echo(f"错误: {e}", err=True)
78
+ raise typer.Exit(1)
79
+ except Exception as e:
80
+ typer.echo(f"请求失败: {e}", err=True)
81
+ raise typer.Exit(1)