intellif-aihub 0.1.22__tar.gz → 0.1.24__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.

Potentially problematic release.


This version of intellif-aihub might be problematic. Click here for more details.

Files changed (74) hide show
  1. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/PKG-INFO +2 -1
  2. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/pyproject.toml +5 -1
  3. intellif_aihub-0.1.24/src/aihub/__init__.py +1 -0
  4. intellif_aihub-0.1.24/src/aihub/cli/__init__.py +1 -0
  5. intellif_aihub-0.1.24/src/aihub/cli/__main__.py +8 -0
  6. intellif_aihub-0.1.24/src/aihub/cli/config.py +136 -0
  7. intellif_aihub-0.1.24/src/aihub/cli/main.py +295 -0
  8. intellif_aihub-0.1.24/src/aihub/cli/model_center.py +355 -0
  9. intellif_aihub-0.1.24/src/aihub/models/model_center.py +128 -0
  10. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/eval.py +2 -2
  11. intellif_aihub-0.1.24/src/aihub/services/model_center.py +331 -0
  12. intellif_aihub-0.1.24/src/aihub/utils/s3.py +120 -0
  13. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/intellif_aihub.egg-info/PKG-INFO +2 -1
  14. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/intellif_aihub.egg-info/SOURCES.txt +6 -0
  15. intellif_aihub-0.1.24/src/intellif_aihub.egg-info/entry_points.txt +2 -0
  16. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/intellif_aihub.egg-info/requires.txt +1 -0
  17. intellif_aihub-0.1.24/tests/test_model_center.py +84 -0
  18. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_task_center.py +7 -0
  19. intellif_aihub-0.1.22/src/aihub/__init__.py +0 -1
  20. intellif_aihub-0.1.22/src/aihub/models/model_center.py +0 -159
  21. intellif_aihub-0.1.22/src/aihub/services/model_center.py +0 -183
  22. intellif_aihub-0.1.22/src/aihub/utils/s3.py +0 -77
  23. intellif_aihub-0.1.22/tests/test_model_center.py +0 -62
  24. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/LICENSE +0 -0
  25. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/README.md +0 -0
  26. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/setup.cfg +0 -0
  27. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/client.py +0 -0
  28. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/exceptions.py +0 -0
  29. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/__init__.py +0 -0
  30. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/artifact.py +0 -0
  31. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/common.py +0 -0
  32. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/data_warehouse.py +0 -0
  33. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/dataset_management.py +0 -0
  34. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/document_center.py +0 -0
  35. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/eval.py +0 -0
  36. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/labelfree.py +0 -0
  37. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/model_training_platform.py +0 -0
  38. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/quota_schedule_management.py +0 -0
  39. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/tag_resource_management.py +0 -0
  40. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/task_center.py +0 -0
  41. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/user_system.py +0 -0
  42. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/models/workflow_center.py +0 -0
  43. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/__init__.py +0 -0
  44. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/artifact.py +0 -0
  45. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/data_warehouse.py +0 -0
  46. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/dataset_management.py +0 -0
  47. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/document_center.py +0 -0
  48. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/labelfree.py +0 -0
  49. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/model_training_platform.py +0 -0
  50. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/quota_schedule_management.py +0 -0
  51. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/reporter.py +0 -0
  52. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/tag_resource_management.py +0 -0
  53. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/task_center.py +0 -0
  54. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/user_system.py +0 -0
  55. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/services/workflow_center.py +0 -0
  56. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/utils/__init__.py +0 -0
  57. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/utils/di.py +0 -0
  58. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/utils/download.py +0 -0
  59. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/aihub/utils/http.py +0 -0
  60. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/intellif_aihub.egg-info/dependency_links.txt +0 -0
  61. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/src/intellif_aihub.egg-info/top_level.txt +0 -0
  62. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_artifact.py +0 -0
  63. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_data_warehouse.py +0 -0
  64. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_dataset_management.py +0 -0
  65. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_di.py +0 -0
  66. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_document_center.py +0 -0
  67. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_eval.py +0 -0
  68. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_labelfree.py +0 -0
  69. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_model_training_platform.py +0 -0
  70. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_quota_schedule_management.py +0 -0
  71. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_s3.py +0 -0
  72. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_tag_resource_management.py +0 -0
  73. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_user_system.py +0 -0
  74. {intellif_aihub-0.1.22 → intellif_aihub-0.1.24}/tests/test_workflow_center.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: intellif-aihub
3
- Version: 0.1.22
3
+ Version: 0.1.24
4
4
  Summary: Intellif AI-hub SDK.
5
5
  Author-email: Platform Team <aihub@example.com>
6
6
  License-Expression: Apache-2.0
@@ -18,6 +18,7 @@ Requires-Dist: tqdm<5.0,>=4.66
18
18
  Requires-Dist: loguru>=0.7.3
19
19
  Requires-Dist: minio>=7.2.7
20
20
  Requires-Dist: requests>=2.32.4
21
+ Requires-Dist: typer>=0.12.0
21
22
  Dynamic: license-file
22
23
 
23
24
  # Intellif AI-Hub SDK
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "intellif-aihub"
3
- version = "0.1.22"
3
+ version = "0.1.24"
4
4
  description = "Intellif AI-hub SDK."
5
5
  readme = {file = "README.md", content-type = "text/markdown"}
6
6
  requires-python = ">=3.9"
@@ -20,8 +20,12 @@ dependencies = [
20
20
  "loguru>=0.7.3",
21
21
  "minio>=7.2.7",
22
22
  "requests>=2.32.4",
23
+ "typer>=0.12.0",
23
24
  ]
24
25
 
26
+ [project.scripts]
27
+ aihub = "aihub.cli.main:app"
28
+
25
29
 
26
30
  [build-system]
27
31
  requires = ["setuptools>=61", "wheel"]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.24"
@@ -0,0 +1 @@
1
+ # CLI module for aihub SDK
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """CLI 工具主入口脚本"""
4
+
5
+ from .main import app
6
+
7
+ if __name__ == "__main__":
8
+ app()
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """CLI 配置管理模块"""
4
+
5
+ import json
6
+ import os
7
+ from pathlib import Path
8
+ from typing import Dict, Optional
9
+
10
+
11
+ class ConfigError(Exception):
12
+ """配置相关错误"""
13
+
14
+ pass
15
+
16
+
17
+ class Config:
18
+ """CLI 配置管理类"""
19
+
20
+ def __init__(self, config_file: Optional[str] = None):
21
+ """初始化配置管理
22
+
23
+ Args:
24
+ config_file: 配置文件路径,如果不提供则使用默认路径
25
+ """
26
+ if config_file:
27
+ self.config_file = Path(config_file)
28
+ else:
29
+ # 默认配置文件路径:~/.aihub/config.json
30
+ config_dir = Path.home() / ".aihub"
31
+ config_dir.mkdir(exist_ok=True)
32
+ self.config_file = config_dir / "config.json"
33
+
34
+ def _load_config(self) -> Dict[str, str]:
35
+ """加载配置文件"""
36
+ if not self.config_file.exists():
37
+ return {}
38
+
39
+ try:
40
+ with open(self.config_file, "r", encoding="utf-8") as f:
41
+ return json.load(f)
42
+ except (json.JSONDecodeError, IOError) as e:
43
+ raise ConfigError(f"无法读取配置文件 {self.config_file}: {e}")
44
+
45
+ def _save_config(self, config: Dict[str, str]) -> None:
46
+ """保存配置文件"""
47
+ try:
48
+ # 确保目录存在
49
+ self.config_file.parent.mkdir(parents=True, exist_ok=True)
50
+
51
+ with open(self.config_file, "w", encoding="utf-8") as f:
52
+ json.dump(config, f, indent=2, ensure_ascii=False)
53
+ except IOError as e:
54
+ raise ConfigError(f"无法写入配置文件 {self.config_file}: {e}")
55
+
56
+ def get(self, key: str) -> Optional[str]:
57
+ """获取配置项
58
+
59
+ Args:
60
+ key: 配置项名称
61
+
62
+ Returns:
63
+ 配置项值,如果不存在则返回 None
64
+ """
65
+ # 优先从环境变量获取
66
+ env_key = f"AIHUB_{key.upper()}"
67
+ env_value = os.getenv(env_key)
68
+ if env_value:
69
+ return env_value
70
+
71
+ # 从配置文件获取
72
+ config = self._load_config()
73
+ return config.get(key)
74
+
75
+ def set(self, key: str, value: str) -> None:
76
+ """设置配置项
77
+
78
+ Args:
79
+ key: 配置项名称
80
+ value: 配置项值
81
+ """
82
+ config = self._load_config()
83
+ config[key] = value
84
+ self._save_config(config)
85
+
86
+ def list_all(self) -> Dict[str, str]:
87
+ """列出所有配置项
88
+
89
+ Returns:
90
+ 所有配置项的字典
91
+ """
92
+ config = self._load_config()
93
+
94
+ # 合并环境变量
95
+ for key in ["base_url", "token"]:
96
+ env_key = f"AIHUB_{key.upper()}"
97
+ env_value = os.getenv(env_key)
98
+ if env_value:
99
+ config[key] = env_value
100
+
101
+ return config
102
+
103
+ def delete(self, key: str) -> bool:
104
+ """删除配置项
105
+
106
+ Args:
107
+ key: 配置项名称
108
+
109
+ Returns:
110
+ 是否成功删除
111
+ """
112
+ config = self._load_config()
113
+ if key in config:
114
+ del config[key]
115
+ self._save_config(config)
116
+ return True
117
+ return False
118
+
119
+
120
+ # 全局配置实例
121
+ _config_instance: Optional[Config] = None
122
+
123
+
124
+ def get_config(config_file: Optional[str] = None) -> Config:
125
+ """获取配置实例(单例模式)
126
+
127
+ Args:
128
+ config_file: 配置文件路径
129
+
130
+ Returns:
131
+ 配置实例
132
+ """
133
+ global _config_instance
134
+ if _config_instance is None:
135
+ _config_instance = Config(config_file)
136
+ return _config_instance
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """AI-HUB SDK CLI 主入口
4
+
5
+ 提供命令行接口来使用 AI-HUB SDK 的各项功能
6
+ """
7
+
8
+ import sys
9
+ from typing import Optional
10
+
11
+ import typer
12
+ from loguru import logger
13
+
14
+ from .config import get_config, ConfigError
15
+ from .model_center import model_app
16
+ from ..client import Client
17
+
18
+ # 创建主应用
19
+ app = typer.Typer(
20
+ name="aihub",
21
+ help="AI-HUB SDK 命令行工具",
22
+ no_args_is_help=True,
23
+ rich_markup_mode="rich",
24
+ )
25
+
26
+ # 添加子命令
27
+ app.add_typer(model_app, name="model", help="模型中心相关命令")
28
+ # app.add_typer(dataset_app, name="dataset", help="数据集管理相关命令")
29
+
30
+
31
+ def version_callback(value: bool):
32
+ """显示版本信息"""
33
+ if value:
34
+ typer.echo("AI-HUB SDK CLI v0.1.0")
35
+ raise typer.Exit()
36
+
37
+
38
+ @app.callback()
39
+ def main(
40
+ version: Optional[bool] = typer.Option(None, "--version", "-v", callback=version_callback, help="显示版本信息"),
41
+ verbose: bool = typer.Option(False, "--verbose", help="启用详细日志输出"),
42
+ config_file: Optional[str] = typer.Option(None, "--config", "-c", help="指定配置文件路径"),
43
+ ):
44
+ """AI-HUB SDK 命令行工具
45
+
46
+ 使用此工具可以通过命令行操作 AI-HUB 平台的各项功能,包括:
47
+ - 模型管理(上传、下载、列表等)
48
+ - 数据集管理(创建、上传、下载等)
49
+
50
+ 首次使用前请配置 base_url 和 token:
51
+ aihub config init --base-url https://your-aihub-server.com --token your-access-token
52
+
53
+ 或使用传统方式:
54
+ aihub config manage set base_url https://your-aihub-server.com
55
+ aihub config manage set token your-access-token
56
+ """
57
+ # 设置日志级别
58
+ log_level = "DEBUG" if verbose else "INFO"
59
+ logger.remove()
60
+ logger.add(
61
+ sys.stderr,
62
+ colorize=True,
63
+ format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <level>{message}</level>",
64
+ level=log_level,
65
+ )
66
+
67
+
68
+ # 创建 config 子应用
69
+ config_app = typer.Typer(
70
+ name="config",
71
+ help="配置管理",
72
+ no_args_is_help=True,
73
+ )
74
+
75
+ # 添加 config 子命令到主应用
76
+ app.add_typer(config_app, name="config", help="配置管理相关命令")
77
+
78
+
79
+ @config_app.command("init")
80
+ def config_init(
81
+ base_url: Optional[str] = typer.Option("http://192.168.99.63:30021", "--base-url", help="AI-HUB 服务器地址"),
82
+ token: Optional[str] = typer.Option(None, "--token", help="访问令牌"),
83
+ ):
84
+ """初始化配置
85
+
86
+ 使用选项参数快速设置 base_url 和 token
87
+ base_url 有默认值 https://api.aihub.com,如需使用其他地址请指定
88
+
89
+ 示例:
90
+ aihub config init --token your-token # 使用默认 base_url
91
+ aihub config init --base-url https://your-server.com --token your-token
92
+ """
93
+ try:
94
+ config_obj = get_config()
95
+
96
+ # 由于 base_url 现在有默认值,只有当 token 也为 None 时才报错
97
+ if not token:
98
+ typer.echo("错误: 需要提供 --token 参数", err=True)
99
+ raise typer.Exit(1)
100
+
101
+ success_count = 0
102
+ total_count = 0
103
+
104
+ # base_url 现在总是有值(要么是用户提供的,要么是默认值)
105
+ if base_url:
106
+ total_count += 1
107
+ try:
108
+ config_obj.set("base_url", base_url)
109
+ typer.echo(f"✅ 已设置 base_url = {base_url}")
110
+ success_count += 1
111
+ except Exception as e:
112
+ typer.echo(f"❌ 设置 base_url 失败: {e}", err=True)
113
+
114
+ if token:
115
+ total_count += 1
116
+ try:
117
+ config_obj.set("token", token)
118
+ # 隐藏 token 的部分内容用于显示
119
+ display_token = f"{token[:8]}..." if len(token) > 8 else token
120
+ typer.echo(f"✅ 已设置 token = {display_token}")
121
+ success_count += 1
122
+ except Exception as e:
123
+ typer.echo(f"❌ 设置 token 失败: {e}", err=True)
124
+
125
+ if success_count == total_count:
126
+ typer.echo(f"\n🎉 配置初始化完成!成功设置 {success_count} 个参数")
127
+ else:
128
+ typer.echo(f"\n⚠️ 配置初始化部分完成,成功设置 {success_count}/{total_count} 个参数")
129
+ raise typer.Exit(1)
130
+
131
+ except typer.Exit:
132
+ raise
133
+ except Exception as e:
134
+ typer.echo(f"❌ 配置初始化失败: {e}", err=True)
135
+ raise typer.Exit(1)
136
+
137
+
138
+ @config_app.command("manage")
139
+ def config_manage(
140
+ action: str = typer.Argument(..., help="操作类型: set, get, list, delete, batch-set"),
141
+ key: Optional[str] = typer.Argument(None, help="配置项名称"),
142
+ value: Optional[str] = typer.Argument(None, help="配置项值"),
143
+ batch_params: Optional[str] = typer.Option(
144
+ None, "--batch", "-b", help="批量设置参数,格式: key1=value1,key2=value2"
145
+ ),
146
+ ):
147
+ """配置管理(传统方式)
148
+
149
+ 支持的配置项:
150
+ - base_url: AI-HUB 服务器地址
151
+ - token: 访问令牌
152
+
153
+ 示例:
154
+ # 单个设置
155
+ aihub config manage set base_url https://your-server.com
156
+ aihub config manage set token your-token
157
+
158
+ # 批量设置
159
+ aihub config manage batch-set --batch "base_url=https://your-server.com,token=your-token"
160
+ aihub config manage set --batch "base_url=https://your-server.com,token=your-token"
161
+
162
+ # 其他操作
163
+ aihub config manage get base_url
164
+ aihub config manage list
165
+ aihub config manage delete token
166
+ """
167
+ try:
168
+ config_obj = get_config()
169
+
170
+ if action == "set":
171
+ # 支持批量设置
172
+ if batch_params:
173
+ _batch_set_config(config_obj, batch_params)
174
+ elif key and value:
175
+ config_obj.set(key, value)
176
+ typer.echo(f"✅ 已设置 {key} = {value}")
177
+ else:
178
+ typer.echo("错误: set 操作需要提供 key 和 value,或使用 --batch 参数", err=True)
179
+ raise typer.Exit(1)
180
+
181
+ elif action == "batch-set":
182
+ if not batch_params:
183
+ typer.echo("错误: batch-set 操作需要提供 --batch 参数", err=True)
184
+ raise typer.Exit(1)
185
+ _batch_set_config(config_obj, batch_params)
186
+
187
+ elif action == "get":
188
+ if not key:
189
+ typer.echo("错误: get 操作需要提供 key", err=True)
190
+ raise typer.Exit(1)
191
+ value = config_obj.get(key)
192
+ if value:
193
+ typer.echo(f"{key} = {value}")
194
+ else:
195
+ typer.echo(f"配置项 {key} 未设置")
196
+
197
+ elif action == "list":
198
+ config_dict = config_obj.list_all()
199
+ if config_dict:
200
+ typer.echo("当前配置:")
201
+ for k, v in config_dict.items():
202
+ # 隐藏 token 的部分内容
203
+ if k == "token" and v:
204
+ display_value = f"{v[:8]}..." if len(v) > 8 else v
205
+ else:
206
+ display_value = v
207
+ typer.echo(f" {k} = {display_value}")
208
+ else:
209
+ typer.echo("暂无配置项")
210
+
211
+ elif action == "delete":
212
+ if not key:
213
+ typer.echo("错误: delete 操作需要提供 key", err=True)
214
+ raise typer.Exit(1)
215
+ config_obj.delete(key)
216
+ typer.echo(f"✅ 已删除配置项 {key}")
217
+
218
+ else:
219
+ typer.echo(f"错误: 不支持的操作 '{action}'", err=True)
220
+ typer.echo("支持的操作: set, get, list, delete, batch-set")
221
+ raise typer.Exit(1)
222
+
223
+ except Exception as e:
224
+ typer.echo(f"❌ 配置操作失败: {e}", err=True)
225
+ raise typer.Exit(1)
226
+
227
+
228
+ def _batch_set_config(config_obj, batch_params: str):
229
+ """批量设置配置参数"""
230
+ try:
231
+ # 解析批量参数
232
+ params = {}
233
+ for param in batch_params.split(","):
234
+ param = param.strip()
235
+ if "=" not in param:
236
+ typer.echo(f"错误: 参数格式不正确 '{param}',应为 key=value", err=True)
237
+ raise typer.Exit(1)
238
+
239
+ key, value = param.split("=", 1)
240
+ key = key.strip()
241
+ value = value.strip()
242
+
243
+ if not key or not value:
244
+ typer.echo(f"错误: 参数不能为空 '{param}'", err=True)
245
+ raise typer.Exit(1)
246
+
247
+ params[key] = value
248
+
249
+ if not params:
250
+ typer.echo("错误: 没有有效的参数", err=True)
251
+ raise typer.Exit(1)
252
+
253
+ # 批量设置
254
+ success_count = 0
255
+ for key, value in params.items():
256
+ try:
257
+ config_obj.set(key, value)
258
+ typer.echo(f"✅ 已设置 {key} = {value}")
259
+ success_count += 1
260
+ except Exception as e:
261
+ typer.echo(f"❌ 设置 {key} 失败: {e}", err=True)
262
+
263
+ typer.echo(f"\n🎉 批量设置完成,成功设置 {success_count}/{len(params)} 个参数")
264
+
265
+ except typer.Exit:
266
+ raise
267
+ except Exception as e:
268
+ typer.echo(f"❌ 批量设置失败: {e}", err=True)
269
+ raise typer.Exit(1)
270
+
271
+
272
+ def get_client() -> Client:
273
+ """获取配置好的客户端实例"""
274
+ try:
275
+ config_obj = get_config()
276
+ base_url = config_obj.get("base_url")
277
+ token = config_obj.get("token")
278
+
279
+ if not base_url:
280
+ typer.echo("错误: 未配置 base_url,请先运行: aihub config init --base-url <your-server-url>", err=True)
281
+ raise typer.Exit(1)
282
+
283
+ if not token:
284
+ typer.echo("错误: 未配置 token,请先运行: aihub config init --token <your-token>", err=True)
285
+ raise typer.Exit(1)
286
+
287
+ return Client(base_url=base_url, token=token, log_level="INFO")
288
+
289
+ except ConfigError as e:
290
+ typer.echo(f"配置错误: {e}", err=True)
291
+ raise typer.Exit(1)
292
+
293
+
294
+ if __name__ == "__main__":
295
+ app()