zerone-cli 0.1.7__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.
- zerone_cli-0.3.1/PKG-INFO +187 -0
- zerone_cli-0.3.1/README.md +160 -0
- zerone_cli-0.3.1/cli/client.py +173 -0
- zerone_cli-0.3.1/cli/commands/__init__.py +23 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/commands/entity_financial_list.py +1 -1
- zerone_cli-0.3.1/cli/commands/execute_aggregate_query.py +73 -0
- zerone_cli-0.3.1/cli/commands/execute_query.py +81 -0
- zerone_cli-0.3.1/cli/commands/get_available_tables.py +28 -0
- zerone_cli-0.3.1/cli/commands/get_table_schema.py +30 -0
- zerone_cli-0.3.1/cli/main.py +38 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/pyproject.toml +1 -1
- zerone_cli-0.3.1/zerone_cli.egg-info/PKG-INFO +187 -0
- zerone_cli-0.3.1/zerone_cli.egg-info/SOURCES.txt +26 -0
- zerone_cli-0.1.7/PKG-INFO +0 -169
- zerone_cli-0.1.7/README.md +0 -142
- zerone_cli-0.1.7/cli/client.py +0 -422
- zerone_cli-0.1.7/cli/commands/__init__.py +0 -19
- zerone_cli-0.1.7/cli/commands/basic_info.py +0 -77
- zerone_cli-0.1.7/cli/commands/entity_exit_list.py +0 -47
- zerone_cli-0.1.7/cli/commands/entity_invest_list.py +0 -47
- zerone_cli-0.1.7/cli/commands/entity_managed_funds_list.py +0 -42
- zerone_cli-0.1.7/cli/commands/evt_company_financing.py +0 -48
- zerone_cli-0.1.7/cli/commands/evt_company_ipo.py +0 -48
- zerone_cli-0.1.7/cli/commands/evt_company_repurchase.py +0 -48
- zerone_cli-0.1.7/cli/commands/evt_company_secondary.py +0 -48
- zerone_cli-0.1.7/cli/commands/evt_listing_company_reduction.py +0 -48
- zerone_cli-0.1.7/cli/commands/evt_listing_company_unlock.py +0 -48
- zerone_cli-0.1.7/cli/commands/evt_lp_investment.py +0 -46
- zerone_cli-0.1.7/cli/commands/evt_ma_company_deal.py +0 -48
- zerone_cli-0.1.7/cli/commands/evt_s_fund_deal.py +0 -46
- zerone_cli-0.1.7/cli/commands/financing.py +0 -84
- zerone_cli-0.1.7/cli/commands/shareholders.py +0 -88
- zerone_cli-0.1.7/cli/main.py +0 -49
- zerone_cli-0.1.7/zerone_cli.egg-info/PKG-INFO +0 -169
- zerone_cli-0.1.7/zerone_cli.egg-info/SOURCES.txt +0 -37
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/__init__.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/commands/config_cmd.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/commands/entity_profile.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/commands/entity_search.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/commands/model_company_match_gp.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/commands/model_financing_probability.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/config.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/utils/__init__.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/utils/errors.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/cli/utils/output.py +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/setup.cfg +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/zerone_cli.egg-info/dependency_links.txt +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/zerone_cli.egg-info/entry_points.txt +0 -0
- {zerone_cli-0.1.7 → zerone_cli-0.3.1}/zerone_cli.egg-info/requires.txt +0 -0
- {zerone_cli-0.1.7 → 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
|
+
]
|
|
@@ -13,7 +13,7 @@ def entity_financial_list(
|
|
|
13
13
|
help="实体类型:LISTED/PREIPO/NEEQ"
|
|
14
14
|
),
|
|
15
15
|
page: int = typer.Option(1, "--page", "-p", help="页码,从 1 开始"),
|
|
16
|
-
page_size: int = typer.Option(
|
|
16
|
+
page_size: int = typer.Option(50, "--page-size", "-s", help="每页条数,默认 50"),
|
|
17
17
|
output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
|
|
18
18
|
):
|
|
19
19
|
"""
|
|
@@ -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)
|