zerone-cli 0.1.3__tar.gz → 0.1.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 (31) hide show
  1. {zerone_cli-0.1.3 → zerone_cli-0.1.4}/PKG-INFO +3 -3
  2. {zerone_cli-0.1.3 → zerone_cli-0.1.4}/README.md +2 -2
  3. {zerone_cli-0.1.3 → zerone_cli-0.1.4}/pyproject.toml +1 -1
  4. {zerone_cli-0.1.3 → zerone_cli-0.1.4}/zerone_cli.egg-info/PKG-INFO +3 -3
  5. zerone_cli-0.1.4/zerone_cli.egg-info/SOURCES.txt +8 -0
  6. zerone_cli-0.1.4/zerone_cli.egg-info/top_level.txt +1 -0
  7. zerone_cli-0.1.3/cli/__init__.py +0 -1
  8. zerone_cli-0.1.3/cli/client.py +0 -176
  9. zerone_cli-0.1.3/cli/commands/__init__.py +0 -19
  10. zerone_cli-0.1.3/cli/commands/basic_info.py +0 -77
  11. zerone_cli-0.1.3/cli/commands/config_cmd.py +0 -47
  12. zerone_cli-0.1.3/cli/commands/entity_exit_list.py +0 -47
  13. zerone_cli-0.1.3/cli/commands/entity_financial_list.py +0 -42
  14. zerone_cli-0.1.3/cli/commands/entity_invest_list.py +0 -47
  15. zerone_cli-0.1.3/cli/commands/entity_managed_funds_list.py +0 -42
  16. zerone_cli-0.1.3/cli/commands/entity_profile.py +0 -40
  17. zerone_cli-0.1.3/cli/commands/entity_search.py +0 -31
  18. zerone_cli-0.1.3/cli/commands/financing.py +0 -84
  19. zerone_cli-0.1.3/cli/commands/model_financing_probability.py +0 -39
  20. zerone_cli-0.1.3/cli/commands/shareholders.py +0 -88
  21. zerone_cli-0.1.3/cli/config.py +0 -69
  22. zerone_cli-0.1.3/cli/main.py +0 -29
  23. zerone_cli-0.1.3/cli/utils/__init__.py +0 -3
  24. zerone_cli-0.1.3/cli/utils/errors.py +0 -0
  25. zerone_cli-0.1.3/cli/utils/output.py +0 -97
  26. zerone_cli-0.1.3/zerone_cli.egg-info/SOURCES.txt +0 -27
  27. zerone_cli-0.1.3/zerone_cli.egg-info/top_level.txt +0 -1
  28. {zerone_cli-0.1.3 → zerone_cli-0.1.4}/setup.cfg +0 -0
  29. {zerone_cli-0.1.3 → zerone_cli-0.1.4}/zerone_cli.egg-info/dependency_links.txt +0 -0
  30. {zerone_cli-0.1.3 → zerone_cli-0.1.4}/zerone_cli.egg-info/entry_points.txt +0 -0
  31. {zerone_cli-0.1.3 → zerone_cli-0.1.4}/zerone_cli.egg-info/requires.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zerone-cli
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Zerone 私募股权数据 CLI 工具
5
5
  Author-email: Zerone <tech@zerone.com.cn>
6
6
  License: MIT
@@ -67,10 +67,10 @@ zerone entity-financial-list "中国石油" --page 1 --page-size 20
67
67
  zerone entity-managed-funds-list "深创投" --page 1 --page-size 20
68
68
 
69
69
  # 查询退出列表
70
- zerone entity-exit-list "深创投" --exit-type IPO --page 1 --page-size 20
70
+ zerone entity-exit-list "深创投" --exit-type FUND --page 1 --page-size 20
71
71
 
72
72
  # 查询投资列表
73
- zerone entity-invest-list "深创投" --invest-type 直接投资 --page 1 --page-size 20
73
+ zerone entity-invest-list "深创投" --invest-type COMPANY --page 1 --page-size 20
74
74
 
75
75
  # 查询融资概率预测
76
76
  zerone model-financing-probability "字节跳动" --type COMPANY
@@ -40,10 +40,10 @@ zerone entity-financial-list "中国石油" --page 1 --page-size 20
40
40
  zerone entity-managed-funds-list "深创投" --page 1 --page-size 20
41
41
 
42
42
  # 查询退出列表
43
- zerone entity-exit-list "深创投" --exit-type IPO --page 1 --page-size 20
43
+ zerone entity-exit-list "深创投" --exit-type FUND --page 1 --page-size 20
44
44
 
45
45
  # 查询投资列表
46
- zerone entity-invest-list "深创投" --invest-type 直接投资 --page 1 --page-size 20
46
+ zerone entity-invest-list "深创投" --invest-type COMPANY --page 1 --page-size 20
47
47
 
48
48
  # 查询融资概率预测
49
49
  zerone model-financing-probability "字节跳动" --type COMPANY
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "zerone-cli"
3
- version = "0.1.3"
3
+ version = "0.1.4"
4
4
  description = "Zerone 私募股权数据 CLI 工具"
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zerone-cli
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Zerone 私募股权数据 CLI 工具
5
5
  Author-email: Zerone <tech@zerone.com.cn>
6
6
  License: MIT
@@ -67,10 +67,10 @@ zerone entity-financial-list "中国石油" --page 1 --page-size 20
67
67
  zerone entity-managed-funds-list "深创投" --page 1 --page-size 20
68
68
 
69
69
  # 查询退出列表
70
- zerone entity-exit-list "深创投" --exit-type IPO --page 1 --page-size 20
70
+ zerone entity-exit-list "深创投" --exit-type FUND --page 1 --page-size 20
71
71
 
72
72
  # 查询投资列表
73
- zerone entity-invest-list "深创投" --invest-type 直接投资 --page 1 --page-size 20
73
+ zerone entity-invest-list "深创投" --invest-type COMPANY --page 1 --page-size 20
74
74
 
75
75
  # 查询融资概率预测
76
76
  zerone model-financing-probability "字节跳动" --type COMPANY
@@ -0,0 +1,8 @@
1
+ README.md
2
+ pyproject.toml
3
+ zerone_cli.egg-info/PKG-INFO
4
+ zerone_cli.egg-info/SOURCES.txt
5
+ zerone_cli.egg-info/dependency_links.txt
6
+ zerone_cli.egg-info/entry_points.txt
7
+ zerone_cli.egg-info/requires.txt
8
+ zerone_cli.egg-info/top_level.txt
@@ -1 +0,0 @@
1
- __version__ = "1.0.0"
@@ -1,176 +0,0 @@
1
- from typing import 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=30.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
- def entity_search(self, keyword: str) -> dict:
59
- return self._request(
60
- "POST",
61
- "/rest-api/tool/entity_search",
62
- json_data={"keyword": keyword},
63
- )
64
-
65
- def entity_profile(
66
- self,
67
- entity_name: str,
68
- entity_type: Optional[str] = None,
69
- ) -> dict:
70
- return self._request(
71
- "POST",
72
- "/rest-api/tool/entity_profile",
73
- json_data={
74
- "entity_name": entity_name,
75
- "entity_type": entity_type or "",
76
- },
77
- )
78
-
79
- def entity_financial_list(
80
- self,
81
- entity_name: str,
82
- entity_type: Optional[str] = None,
83
- page: int = 1,
84
- page_size: int = 20,
85
- ) -> dict:
86
- return self._request(
87
- "POST",
88
- "/rest-api/tool/entity_financial_list",
89
- json_data={
90
- "entity_name": entity_name,
91
- "entity_type": entity_type or "",
92
- "page": page,
93
- "page_size": page_size,
94
- },
95
- )
96
-
97
- def entity_managed_funds_list(
98
- self,
99
- entity_name: str,
100
- entity_type: Optional[str] = None,
101
- page: int = 1,
102
- page_size: int = 20,
103
- ) -> dict:
104
- return self._request(
105
- "POST",
106
- "/rest-api/tool/entity_managed_funds_list",
107
- json_data={
108
- "entity_name": entity_name,
109
- "entity_type": entity_type or "",
110
- "page": page,
111
- "page_size": page_size,
112
- },
113
- )
114
-
115
- def entity_exit_list(
116
- self,
117
- entity_name: str,
118
- entity_type: Optional[str] = None,
119
- exit_type: Optional[str] = None,
120
- page: int = 1,
121
- page_size: int = 20,
122
- ) -> dict:
123
- return self._request(
124
- "POST",
125
- "/rest-api/tool/entity_exit_list",
126
- json_data={
127
- "entity_name": entity_name,
128
- "entity_type": entity_type or "",
129
- "exit_type": exit_type or "",
130
- "page": page,
131
- "page_size": page_size,
132
- },
133
- )
134
-
135
- def entity_invest_list(
136
- self,
137
- entity_name: str,
138
- entity_type: Optional[str] = None,
139
- invest_type: Optional[str] = None,
140
- page: int = 1,
141
- page_size: int = 20,
142
- ) -> dict:
143
- return self._request(
144
- "POST",
145
- "/rest-api/tool/entity_invest_list",
146
- json_data={
147
- "entity_name": entity_name,
148
- "entity_type": entity_type or "",
149
- "invest_type": invest_type or "",
150
- "page": page,
151
- "page_size": page_size,
152
- },
153
- )
154
-
155
- def model_financing_probability(
156
- self,
157
- entity_name: str,
158
- entity_type: Optional[str] = None,
159
- ) -> dict:
160
- return self._request(
161
- "POST",
162
- "/rest-api/tool/model_financing_probability",
163
- json_data={
164
- "entity_name": entity_name,
165
- "entity_type": entity_type or "",
166
- },
167
- )
168
-
169
- def close(self):
170
- self.client.close()
171
-
172
- def __enter__(self):
173
- return self
174
-
175
- def __exit__(self, exc_type, exc_val, exc_tb):
176
- self.close()
@@ -1,19 +0,0 @@
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.entity_managed_funds_list import entity_managed_funds_list
6
- from cli.commands.entity_exit_list import entity_exit_list
7
- from cli.commands.entity_invest_list import entity_invest_list
8
- from cli.commands.model_financing_probability import model_financing_probability
9
-
10
- __all__ = [
11
- "config_cmd",
12
- "entity_search",
13
- "entity_profile",
14
- "entity_financial_list",
15
- "entity_managed_funds_list",
16
- "entity_exit_list",
17
- "entity_invest_list",
18
- "model_financing_probability",
19
- ]
@@ -1,77 +0,0 @@
1
- """
2
- 查询基本信息命令模块
3
- """
4
-
5
- import asyncio
6
- from typing import Optional
7
-
8
- import typer
9
-
10
- from cli.config import config_manager
11
- from cli.utils.output import print_result
12
- from mcp_server.tools.executor import ToolExecutor
13
- from mcp_server.router.entity_router import EntityRouter
14
- from mcp_server.router.type_router import TypeRouter
15
- from mcp_server.services.entity_service import EntityService
16
- from mcp_server.utils.field_mapper import FieldMapper
17
- from mcp_server.openapi_client.client import OpenAPIClient
18
-
19
-
20
- async def execute(entity_name: str, entity_type: Optional[str] = None) -> dict:
21
- """
22
- 执行查询基本信息
23
-
24
- Args:
25
- entity_name: 实体名称
26
- entity_type: 实体类型 (gp/lp/fund/company/preipo/list/neeq)
27
-
28
- Returns:
29
- 查询结果字典
30
- """
31
- app_id, app_key = config_manager.get_credentials()
32
- config = config_manager.load()
33
-
34
- client = OpenAPIClient(base_url=config.base_url)
35
- entity_service = EntityService()
36
- executor = ToolExecutor(
37
- entity_router=EntityRouter(entity_service),
38
- type_router=TypeRouter(),
39
- field_mapper=FieldMapper(),
40
- openapi_client=client,
41
- )
42
-
43
- try:
44
- result = await executor.execute_get_basic_info(
45
- entity_name=entity_name,
46
- entity_type=entity_type,
47
- app_id=app_id,
48
- app_key=app_key,
49
- )
50
- return result
51
- finally:
52
- await client.close()
53
-
54
-
55
- def get_basic_info(
56
- entity_name: str = typer.Argument(..., help="实体名称,如'字节跳动'"),
57
- entity_type: Optional[str] = typer.Option(
58
- None, "--type", "-t", help="实体类型:gp/lp/fund/company/preipo/list/neeq"
59
- ),
60
- output: str = typer.Option(
61
- "table", "--output", "-o", help="输出格式:table/json/csv"
62
- ),
63
- ):
64
- """
65
- 查询实体基本信息
66
-
67
- 示例:
68
- zerone-cli get-basic-info "字节跳动"
69
- zerone-cli get-basic-info "红杉资本" --type gp
70
- zerone-cli get-basic-info "字节跳动" --output json
71
- """
72
- try:
73
- result = asyncio.run(execute(entity_name, entity_type))
74
- print_result(result, output)
75
- except ValueError as e:
76
- typer.echo(f"[red]错误: {e}[/red]", err=True)
77
- raise typer.Exit(1)
@@ -1,47 +0,0 @@
1
- import typer
2
-
3
- from cli.config import config_manager
4
-
5
- app = typer.Typer(help="管理 CLI 配置")
6
-
7
-
8
- @app.command("show")
9
- def show_config():
10
- """显示当前配置"""
11
- config = config_manager.load()
12
- typer.echo("=== 当前配置 ===")
13
- typer.echo(f"api_key: {'*' * 10 if config.api_key else '(未设置)'}")
14
- typer.echo(f"server_url: {config.server_url}")
15
- typer.echo(f"output_format: {config.output_format}")
16
-
17
-
18
- @app.command("set-api-key")
19
- def set_api_key(api_key: str = typer.Argument(..., help="API Key(从平台获取)")):
20
- """设置 API Key"""
21
- config = config_manager.load()
22
- config.api_key = api_key
23
- config_manager.save(config)
24
- typer.echo("✓ API Key 已设置")
25
-
26
-
27
- @app.command("set-server-url")
28
- def set_server_url(url: str = typer.Argument(..., help="MCP Server 地址,如 http://localhost:8080")):
29
- """设置 MCP Server 地址"""
30
- config = config_manager.load()
31
- config.server_url = url
32
- config_manager.save(config)
33
- typer.echo(f"✓ Server URL 已设置: {url}")
34
-
35
-
36
- @app.command("set-output-format")
37
- def set_output_format(
38
- fmt: str = typer.Argument(..., help="输出格式 (table/json/csv)")
39
- ):
40
- """设置默认输出格式"""
41
- if fmt not in ("table", "json", "csv"):
42
- typer.echo("✗ 无效的输出格式,请选择: table, json, csv")
43
- raise typer.Exit(1)
44
- config = config_manager.load()
45
- config.output_format = fmt
46
- config_manager.save(config)
47
- typer.echo(f"✓ Output format 已设置: {fmt}")
@@ -1,47 +0,0 @@
1
- from typing import Optional
2
-
3
- import typer
4
-
5
- from cli.client import MCPClient
6
- from cli.utils.output import print_result
7
-
8
-
9
- def entity_exit_list(
10
- entity_name: str = typer.Argument(..., help="实体名称,如'高瓴资本'"),
11
- entity_type: Optional[str] = typer.Option(
12
- None, "--type", "-t",
13
- help="实体类型:GP/LP/FUND"
14
- ),
15
- exit_type: Optional[str] = typer.Option(
16
- None, "--exit-type", "-e",
17
- help="退出类型:COMPANY/FUND"
18
- ),
19
- page: int = typer.Option(1, "--page", "-p", help="页码,从 1 开始"),
20
- page_size: int = typer.Option(20, "--page-size", "-s", help="每页条数,默认 20"),
21
- output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
22
- ):
23
- """
24
- 查询退出列表(分页)
25
-
26
- 支持 GP/LP/FUND 类型。
27
-
28
- 示例:
29
- zerone entity-exit-list "高瓴资本" --type GP
30
- zerone entity-exit-list "高瓴资本" --type GP --exit-type COMPANY
31
- """
32
- try:
33
- with MCPClient() as client:
34
- result = client.entity_exit_list(
35
- entity_name=entity_name,
36
- entity_type=entity_type,
37
- exit_type=exit_type,
38
- page=page,
39
- page_size=page_size,
40
- )
41
- print_result(result, output)
42
- except ValueError as e:
43
- typer.echo(f"错误: {e}", err=True)
44
- raise typer.Exit(1)
45
- except Exception as e:
46
- typer.echo(f"请求失败: {e}", err=True)
47
- raise typer.Exit(1)
@@ -1,42 +0,0 @@
1
- from typing import Optional
2
-
3
- import typer
4
-
5
- from cli.client import MCPClient
6
- from cli.utils.output import print_result
7
-
8
-
9
- def entity_financial_list(
10
- entity_name: str = typer.Argument(..., help="实体名称,如'美团'"),
11
- entity_type: Optional[str] = typer.Option(
12
- None, "--type", "-t",
13
- help="实体类型:LISTED/PREIPO/NEEQ"
14
- ),
15
- page: int = typer.Option(1, "--page", "-p", help="页码,从 1 开始"),
16
- page_size: int = typer.Option(20, "--page-size", "-s", help="每页条数,默认 20"),
17
- output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
18
- ):
19
- """
20
- 查询实体财务数据列表(分页)
21
-
22
- 仅支持 LISTED/PREIPO/NEEQ 类型。
23
-
24
- 示例:
25
- zerone entity-financial-list "美团" --type LISTED
26
- zerone entity-financial-list "美团" --type LISTED --page 2
27
- """
28
- try:
29
- with MCPClient() as client:
30
- result = client.entity_financial_list(
31
- entity_name=entity_name,
32
- entity_type=entity_type,
33
- page=page,
34
- page_size=page_size,
35
- )
36
- print_result(result, output)
37
- except ValueError as e:
38
- typer.echo(f"错误: {e}", err=True)
39
- raise typer.Exit(1)
40
- except Exception as e:
41
- typer.echo(f"请求失败: {e}", err=True)
42
- raise typer.Exit(1)
@@ -1,47 +0,0 @@
1
- from typing import Optional
2
-
3
- import typer
4
-
5
- from cli.client import MCPClient
6
- from cli.utils.output import print_result
7
-
8
-
9
- def entity_invest_list(
10
- entity_name: str = typer.Argument(..., help="实体名称,如'高瓴资本'"),
11
- entity_type: Optional[str] = typer.Option(
12
- None, "--type", "-t",
13
- help="实体类型:GP/LP/FUND"
14
- ),
15
- invest_type: Optional[str] = typer.Option(
16
- None, "--invest-type", "-i",
17
- help="投资类型:COMPANY/FUND/OTHER"
18
- ),
19
- page: int = typer.Option(1, "--page", "-p", help="页码,从 1 开始"),
20
- page_size: int = typer.Option(20, "--page-size", "-s", help="每页条数,默认 20"),
21
- output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
22
- ):
23
- """
24
- 查询投资列表(分页)
25
-
26
- 支持 GP/LP/FUND 类型。
27
-
28
- 示例:
29
- zerone entity-invest-list "高瓴资本" --type GP
30
- zerone entity-invest-list "高瓴资本" --type GP --invest-type COMPANY
31
- """
32
- try:
33
- with MCPClient() as client:
34
- result = client.entity_invest_list(
35
- entity_name=entity_name,
36
- entity_type=entity_type,
37
- invest_type=invest_type,
38
- page=page,
39
- page_size=page_size,
40
- )
41
- print_result(result, output)
42
- except ValueError as e:
43
- typer.echo(f"错误: {e}", err=True)
44
- raise typer.Exit(1)
45
- except Exception as e:
46
- typer.echo(f"请求失败: {e}", err=True)
47
- raise typer.Exit(1)
@@ -1,42 +0,0 @@
1
- from typing import Optional
2
-
3
- import typer
4
-
5
- from cli.client import MCPClient
6
- from cli.utils.output import print_result
7
-
8
-
9
- def entity_managed_funds_list(
10
- entity_name: str = typer.Argument(..., help="实体名称,如'红杉资本'"),
11
- entity_type: Optional[str] = typer.Option(
12
- None, "--type", "-t",
13
- help="实体类型:GP/FUND_MANAGER"
14
- ),
15
- page: int = typer.Option(1, "--page", "-p", help="页码,从 1 开始"),
16
- page_size: int = typer.Option(20, "--page-size", "-s", help="每页条数,默认 20"),
17
- output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
18
- ):
19
- """
20
- 查询管理基金列表(分页)
21
-
22
- 支持 GP 和 FUND_MANAGER 类型。
23
-
24
- 示例:
25
- zerone entity-managed-funds-list "红杉资本" --type GP
26
- zerone entity-managed-funds-list "红杉资本" --type GP --page 2
27
- """
28
- try:
29
- with MCPClient() as client:
30
- result = client.entity_managed_funds_list(
31
- entity_name=entity_name,
32
- entity_type=entity_type,
33
- page=page,
34
- page_size=page_size,
35
- )
36
- print_result(result, output)
37
- except ValueError as e:
38
- typer.echo(f"错误: {e}", err=True)
39
- raise typer.Exit(1)
40
- except Exception as e:
41
- typer.echo(f"请求失败: {e}", err=True)
42
- raise typer.Exit(1)
@@ -1,40 +0,0 @@
1
- from typing import Optional
2
-
3
- import typer
4
-
5
- from cli.client import MCPClient
6
- from cli.utils.output import print_result
7
-
8
-
9
- def entity_profile(
10
- entity_name: str = typer.Argument(..., help="实体名称,如'字节跳动'"),
11
- entity_type: Optional[str] = typer.Option(
12
- None, "--type", "-t",
13
- help="实体类型:GP/FUND/LP/COMPANY/PREIPO/LISTED/NEEQ/FUND_MANAGER"
14
- ),
15
- output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
16
- ):
17
- """
18
- 查询实体综合画像
19
-
20
- 返回基本信息、标签画像、概览数据、股东列表、融资历史、关联GP列表等。
21
- 支持全部 8 种实体类型:GP/FUND/LP/COMPANY/FUND_MANAGER/PREIPO/LISTED/NEEQ。
22
-
23
- 示例:
24
- zerone entity-profile "字节跳动"
25
- zerone entity-profile "红杉资本" --type GP
26
- zerone entity-profile "字节跳动" --output json
27
- """
28
- try:
29
- with MCPClient() as client:
30
- result = client.entity_profile(
31
- entity_name=entity_name,
32
- entity_type=entity_type,
33
- )
34
- print_result(result, output)
35
- except ValueError as e:
36
- typer.echo(f"错误: {e}", err=True)
37
- raise typer.Exit(1)
38
- except Exception as e:
39
- typer.echo(f"请求失败: {e}", err=True)
40
- raise typer.Exit(1)
@@ -1,31 +0,0 @@
1
- from typing import Optional
2
-
3
- import typer
4
-
5
- from cli.client import MCPClient
6
- from cli.utils.output import print_result
7
-
8
-
9
- def entity_search(
10
- keyword: str = typer.Argument(..., help="搜索关键词"),
11
- output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
12
- ):
13
- """
14
- 实体模糊搜索
15
-
16
- 根据关键词搜索匹配的实体,返回候选实体列表。
17
-
18
- 示例:
19
- zerone entity-search "字节跳动"
20
- zerone entity-search "红杉" --output json
21
- """
22
- try:
23
- with MCPClient() as client:
24
- result = client.entity_search(keyword=keyword)
25
- print_result(result, output)
26
- except ValueError as e:
27
- typer.echo(f"错误: {e}", err=True)
28
- raise typer.Exit(1)
29
- except Exception as e:
30
- typer.echo(f"请求失败: {e}", err=True)
31
- raise typer.Exit(1)
@@ -1,84 +0,0 @@
1
- """
2
- 查询融资概率命令模块
3
- """
4
-
5
- import asyncio
6
- from typing import Optional
7
-
8
- import typer
9
-
10
- from cli.config import config_manager
11
- from cli.utils.output import print_result
12
- from mcp_server.tools.executor import ToolExecutor
13
- from mcp_server.router.entity_router import EntityRouter
14
- from mcp_server.router.type_router import TypeRouter
15
- from mcp_server.services.entity_service import EntityService
16
- from mcp_server.utils.field_mapper import FieldMapper
17
- from mcp_server.openapi_client.client import OpenAPIClient
18
-
19
-
20
- async def execute(
21
- entity_name: str,
22
- entity_type: Optional[str] = None,
23
- ) -> dict:
24
- """
25
- 执行查询融资概率
26
-
27
- 注意:此命令仅支持项目公司类型(company/preipo/list/neeq)
28
-
29
- Args:
30
- entity_name: 实体名称
31
- entity_type: 实体类型
32
-
33
- Returns:
34
- 查询结果字典
35
- """
36
- app_id, app_key = config_manager.get_credentials()
37
- config = config_manager.load()
38
-
39
- client = OpenAPIClient(base_url=config.base_url)
40
- entity_service = EntityService()
41
- executor = ToolExecutor(
42
- entity_router=EntityRouter(entity_service),
43
- type_router=TypeRouter(),
44
- field_mapper=FieldMapper(),
45
- openapi_client=client,
46
- )
47
-
48
- try:
49
- result = await executor.execute_get_financing_probability(
50
- entity_name=entity_name,
51
- entity_type=entity_type,
52
- app_id=app_id,
53
- app_key=app_key,
54
- )
55
- return result
56
- finally:
57
- await client.close()
58
-
59
-
60
- def get_financing_probability(
61
- entity_name: str = typer.Argument(..., help="实体名称,如'字节跳动'"),
62
- entity_type: Optional[str] = typer.Option(
63
- None, "--type", "-t", help="实体类型:company/preipo/list/neeq"
64
- ),
65
- output: str = typer.Option(
66
- "table", "--output", "-o", help="输出格式:table/json/csv"
67
- ),
68
- ):
69
- """
70
- 查询公司融资概率(2年)
71
-
72
- 注意:此命令仅支持项目公司类型(company/preipo/list/neeq)
73
-
74
- 示例:
75
- zerone-cli get-financing-probability "蔚来汽车"
76
- zerone-cli get-financing-probability "字节跳动" --type company
77
- zerone-cli get-financing-probability "蔚来汽车" --output json
78
- """
79
- try:
80
- result = asyncio.run(execute(entity_name, entity_type))
81
- print_result(result, output)
82
- except ValueError as e:
83
- typer.echo(f"[red]错误: {e}[/red]", err=True)
84
- raise typer.Exit(1)
@@ -1,39 +0,0 @@
1
- from typing import Optional
2
-
3
- import typer
4
-
5
- from cli.client import MCPClient
6
- from cli.utils.output import print_result
7
-
8
-
9
- def model_financing_probability(
10
- entity_name: str = typer.Argument(..., help="实体名称,如'蔚来汽车'"),
11
- entity_type: Optional[str] = typer.Option(
12
- None, "--type", "-t",
13
- help="实体类型:COMPANY/PREIPO/LISTED/NEEQ"
14
- ),
15
- output: str = typer.Option("table", "--output", "-o", help="输出格式:table/json/csv"),
16
- ):
17
- """
18
- 查询项目公司融资概率预测模型
19
-
20
- 仅支持 COMPANY/PREIPO/LISTED/NEEQ 类型。
21
- 返回融资概率(2年)和模型指标数据。
22
-
23
- 示例:
24
- zerone model-financing-probability "蔚来汽车"
25
- zerone model-financing-probability "蔚来汽车" --type COMPANY
26
- """
27
- try:
28
- with MCPClient() as client:
29
- result = client.model_financing_probability(
30
- entity_name=entity_name,
31
- entity_type=entity_type,
32
- )
33
- print_result(result, output)
34
- except ValueError as e:
35
- typer.echo(f"错误: {e}", err=True)
36
- raise typer.Exit(1)
37
- except Exception as e:
38
- typer.echo(f"请求失败: {e}", err=True)
39
- raise typer.Exit(1)
@@ -1,88 +0,0 @@
1
- """
2
- 查询股东信息命令模块
3
- """
4
-
5
- import asyncio
6
- from typing import Optional
7
-
8
- import typer
9
-
10
- from cli.config import config_manager
11
- from cli.utils.output import print_result
12
- from mcp_server.tools.executor import ToolExecutor
13
- from mcp_server.router.entity_router import EntityRouter
14
- from mcp_server.router.type_router import TypeRouter
15
- from mcp_server.services.entity_service import EntityService
16
- from mcp_server.utils.field_mapper import FieldMapper
17
- from mcp_server.openapi_client.client import OpenAPIClient
18
-
19
-
20
- async def execute(
21
- entity_name: str,
22
- entity_type: Optional[str] = None,
23
- page: int = 1,
24
- page_size: int = 20,
25
- ) -> dict:
26
- """
27
- 执行查询股东信息
28
-
29
- Args:
30
- entity_name: 实体名称
31
- entity_type: 实体类型
32
- page: 页码,从 1 开始
33
- page_size: 每页数量
34
-
35
- Returns:
36
- 查询结果字典
37
- """
38
- app_id, app_key = config_manager.get_credentials()
39
- config = config_manager.load()
40
-
41
- client = OpenAPIClient(base_url=config.base_url)
42
- entity_service = EntityService()
43
- executor = ToolExecutor(
44
- entity_router=EntityRouter(entity_service),
45
- type_router=TypeRouter(),
46
- field_mapper=FieldMapper(),
47
- openapi_client=client,
48
- )
49
-
50
- try:
51
- result = await executor.execute_get_shareholders(
52
- entity_name=entity_name,
53
- entity_type=entity_type,
54
- page=page,
55
- page_size=page_size,
56
- app_id=app_id,
57
- app_key=app_key,
58
- )
59
- return result
60
- finally:
61
- await client.close()
62
-
63
-
64
- def get_shareholders(
65
- entity_name: str = typer.Argument(..., help="实体名称,如'字节跳动'"),
66
- entity_type: Optional[str] = typer.Option(
67
- None, "--type", "-t", help="实体类型:gp/lp/fund/company/preipo/list/neeq"
68
- ),
69
- page: int = typer.Option(1, "--page", "-p", help="页码"),
70
- page_size: int = typer.Option(20, "--page-size", "-s", help="每页数量"),
71
- output: str = typer.Option(
72
- "table", "--output", "-o", help="输出格式:table/json/csv"
73
- ),
74
- ):
75
- """
76
- 查询实体股东信息(支持分页)
77
-
78
- 示例:
79
- zerone-cli get-shareholders "美团"
80
- zerone-cli get-shareholders "高瓴资本" --type gp --page 1 --page-size 10
81
- zerone-cli get-shareholders "美团" --output csv
82
- """
83
- try:
84
- result = asyncio.run(execute(entity_name, entity_type, page, page_size))
85
- print_result(result, output)
86
- except ValueError as e:
87
- typer.echo(f"[red]错误: {e}[/red]", err=True)
88
- raise typer.Exit(1)
@@ -1,69 +0,0 @@
1
- import os
2
- import yaml
3
- from pathlib import Path
4
- from typing import Optional
5
-
6
- from pydantic import BaseModel
7
-
8
- SERVER_URL_PROD = "https://ai.zerone.com.cn/mcp"
9
- SERVER_URL_DEV = "http://ai-dev.zerone.com.cn/mcp"
10
-
11
- _env = os.getenv("ZERONE_ENV", "prod").lower()
12
- DEFAULT_SERVER_URL = SERVER_URL_DEV if _env == "dev" else SERVER_URL_PROD
13
-
14
-
15
- class CLIConfig(BaseModel):
16
- api_key: Optional[str] = None
17
- server_url: str = DEFAULT_SERVER_URL
18
- output_format: str = "table"
19
-
20
-
21
- class ConfigManager:
22
-
23
- CONFIG_DIR = Path.home() / ".zerone"
24
- CONFIG_FILE = CONFIG_DIR / "config.yaml"
25
-
26
- def __init__(self):
27
- self._config: Optional[CLIConfig] = None
28
-
29
- def _ensure_config_dir(self):
30
- self.CONFIG_DIR.mkdir(parents=True, exist_ok=True)
31
-
32
- def load(self) -> CLIConfig:
33
- if self._config:
34
- return self._config
35
-
36
- if self.CONFIG_FILE.exists():
37
- with open(self.CONFIG_FILE, "r", encoding="utf-8") as f:
38
- data = yaml.safe_load(f) or {}
39
- else:
40
- data = {}
41
-
42
- data["api_key"] = os.getenv("ZERONE_API_KEY", data.get("api_key"))
43
- data["server_url"] = os.getenv("ZERONE_SERVER_URL", data.get("server_url", DEFAULT_SERVER_URL))
44
-
45
- self._config = CLIConfig(**data)
46
- return self._config
47
-
48
- def save(self, config: CLIConfig):
49
- self._ensure_config_dir()
50
- self._config = config
51
- with open(self.CONFIG_FILE, "w", encoding="utf-8") as f:
52
- yaml.dump(config.model_dump(), f, allow_unicode=True, default_flow_style=False)
53
-
54
- def get_api_key(self) -> str:
55
- config = self.load()
56
- if not config.api_key:
57
- raise ValueError(
58
- "未配置 API Key。\n"
59
- "请运行:zerone config set-api-key <your-api-key>\n"
60
- "或设置环境变量:ZERONE_API_KEY"
61
- )
62
- return config.api_key
63
-
64
- def get_server_url(self) -> str:
65
- config = self.load()
66
- return config.server_url
67
-
68
-
69
- config_manager = ConfigManager()
@@ -1,29 +0,0 @@
1
- import typer
2
-
3
- from cli.commands import config_cmd
4
- from cli.commands.entity_search import entity_search
5
- from cli.commands.entity_profile import entity_profile
6
- from cli.commands.entity_financial_list import entity_financial_list
7
- from cli.commands.entity_managed_funds_list import entity_managed_funds_list
8
- from cli.commands.entity_exit_list import entity_exit_list
9
- from cli.commands.entity_invest_list import entity_invest_list
10
- from cli.commands.model_financing_probability import model_financing_probability
11
-
12
- app = typer.Typer(
13
- name="zerone",
14
- help="Zerone 私募股权数据 CLI 工具 - MCP HTTP 客户端",
15
- no_args_is_help=True,
16
- )
17
-
18
- app.add_typer(config_cmd.app, name="config")
19
-
20
- app.command("entity-search")(entity_search)
21
- app.command("entity-profile")(entity_profile)
22
- app.command("entity-financial-list")(entity_financial_list)
23
- app.command("entity-managed-funds-list")(entity_managed_funds_list)
24
- app.command("entity-exit-list")(entity_exit_list)
25
- app.command("entity-invest-list")(entity_invest_list)
26
- app.command("model-financing-probability")(model_financing_probability)
27
-
28
- if __name__ == "__main__":
29
- app()
@@ -1,3 +0,0 @@
1
- from .output import print_result, print_error
2
-
3
- __all__ = ["print_result", "print_error"]
File without changes
@@ -1,97 +0,0 @@
1
- """
2
- CLI 输出格式化模块
3
-
4
- 支持 table、json、csv 三种输出格式。
5
- """
6
-
7
- import csv
8
- import io
9
- import json
10
- from typing import Any
11
-
12
- from rich.console import Console
13
- from rich.table import Table
14
-
15
- console = Console()
16
-
17
-
18
- def print_result(result: dict, output_format: str = "table"):
19
- """
20
- 主入口函数,根据格式输出结果
21
-
22
- Args:
23
- result: 包含 data、metadata 的结果字典
24
- output_format: 输出格式 (table/json/csv)
25
- """
26
- if "error" in result:
27
- print_error(result)
28
- return
29
-
30
- data = result.get("data", {})
31
- metadata = result.get("metadata", {})
32
-
33
- if output_format == "json":
34
- print_json(data)
35
- elif output_format == "csv":
36
- print_csv(data)
37
- else:
38
- print_table(data, metadata)
39
-
40
-
41
- def print_table(data: Any, metadata: dict):
42
- """表格格式输出"""
43
- if isinstance(data, list):
44
- if not data:
45
- console.print("[yellow]没有查询到数据[/yellow]")
46
- return
47
- keys = list(data[0].keys()) if data else []
48
- table = Table(show_header=True, header_style="bold cyan", box=None)
49
- for key in keys:
50
- table.add_column(key, style="white")
51
- for row in data:
52
- table.add_row(*[str(row.get(k, "")) for k in keys])
53
- console.print(table)
54
- elif isinstance(data, dict):
55
- table = Table(show_header=True, header_style="bold cyan", box=None)
56
- table.add_column("字段", style="cyan")
57
- table.add_column("值", style="white")
58
- for key, value in data.items():
59
- table.add_row(key, str(value) if value is not None else "")
60
- console.print(table)
61
- else:
62
- console.print(str(data))
63
-
64
- entity_name = metadata.get("entityName", "")
65
- entity_type = metadata.get("entityType", "")
66
- if entity_name:
67
- console.print(f"\n[dim]实体名称: {entity_name} | 类型: {entity_type}[/dim]")
68
-
69
-
70
- def print_json(data: Any):
71
- """JSON 格式输出"""
72
- console.print(json.dumps(data, ensure_ascii=False, indent=2))
73
-
74
-
75
- def print_csv(data: Any):
76
- """CSV 格式输出"""
77
- output = io.StringIO()
78
- if isinstance(data, list):
79
- if not data:
80
- return
81
- writer = csv.DictWriter(output, fieldnames=data[0].keys())
82
- writer.writeheader()
83
- writer.writerows(data)
84
- elif isinstance(data, dict):
85
- writer = csv.DictWriter(output, fieldnames=data.keys())
86
- writer.writeheader()
87
- writer.writerow(data)
88
- else:
89
- output.write(str(data))
90
- console.print(output.getvalue())
91
-
92
-
93
- def print_error(error: dict):
94
- """错误信息输出"""
95
- code = error.get("code", error.get("error_code", "UNKNOWN"))
96
- message = error.get("message", error.get("msg", "未知错误"))
97
- console.print(f"[bold red]错误 {code}:[/bold red] {message}")
@@ -1,27 +0,0 @@
1
- README.md
2
- pyproject.toml
3
- cli/__init__.py
4
- cli/client.py
5
- cli/config.py
6
- cli/main.py
7
- cli/commands/__init__.py
8
- cli/commands/basic_info.py
9
- cli/commands/config_cmd.py
10
- cli/commands/entity_exit_list.py
11
- cli/commands/entity_financial_list.py
12
- cli/commands/entity_invest_list.py
13
- cli/commands/entity_managed_funds_list.py
14
- cli/commands/entity_profile.py
15
- cli/commands/entity_search.py
16
- cli/commands/financing.py
17
- cli/commands/model_financing_probability.py
18
- cli/commands/shareholders.py
19
- cli/utils/__init__.py
20
- cli/utils/errors.py
21
- cli/utils/output.py
22
- zerone_cli.egg-info/PKG-INFO
23
- zerone_cli.egg-info/SOURCES.txt
24
- zerone_cli.egg-info/dependency_links.txt
25
- zerone_cli.egg-info/entry_points.txt
26
- zerone_cli.egg-info/requires.txt
27
- zerone_cli.egg-info/top_level.txt
@@ -1 +0,0 @@
1
- cli
File without changes