adam-community 1.0.1__tar.gz → 1.0.3__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 (25) hide show
  1. adam_community-1.0.3/PKG-INFO +104 -0
  2. adam_community-1.0.3/README.md +76 -0
  3. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/__init__.py +1 -0
  4. adam_community-1.0.3/adam_community/__version__.py +1 -0
  5. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/cli/build.py +85 -57
  6. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/cli/cli.py +30 -1
  7. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/cli/parser.py +103 -24
  8. adam_community-1.0.3/adam_community/cli/updater.py +201 -0
  9. adam_community-1.0.3/adam_community.egg-info/PKG-INFO +104 -0
  10. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community.egg-info/SOURCES.txt +2 -0
  11. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community.egg-info/requires.txt +2 -0
  12. {adam_community-1.0.1 → adam_community-1.0.3}/setup.py +10 -1
  13. adam_community-1.0.1/PKG-INFO +0 -53
  14. adam_community-1.0.1/README.md +0 -27
  15. adam_community-1.0.1/adam_community.egg-info/PKG-INFO +0 -53
  16. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/cli/__init__.py +0 -0
  17. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/cli/init.py +0 -0
  18. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/cli/templates/__init__.py +0 -0
  19. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/tool.py +0 -0
  20. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community/util.py +0 -0
  21. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community.egg-info/dependency_links.txt +0 -0
  22. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community.egg-info/entry_points.txt +0 -0
  23. {adam_community-1.0.1 → adam_community-1.0.3}/adam_community.egg-info/top_level.txt +0 -0
  24. {adam_community-1.0.1 → adam_community-1.0.3}/setup.cfg +0 -0
  25. {adam_community-1.0.1 → adam_community-1.0.3}/test/test_util_tool.py +0 -0
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.2
2
+ Name: adam_community
3
+ Version: 1.0.3
4
+ Summary: Adam Community Tools and Utilities
5
+ Home-page: https://github.com/yourusername/adam-community
6
+ Author: Adam Community
7
+ Author-email: admin@sidereus-ai.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: requests>=2.31.0
14
+ Requires-Dist: click>=8.0.0
15
+ Requires-Dist: docstring-parser>=0.15
16
+ Requires-Dist: rich>=13.0.0
17
+ Requires-Dist: packaging>=21.0
18
+ Requires-Dist: jsonschema>=4.0.0
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: classifier
22
+ Dynamic: description
23
+ Dynamic: description-content-type
24
+ Dynamic: home-page
25
+ Dynamic: requires-dist
26
+ Dynamic: requires-python
27
+ Dynamic: summary
28
+
29
+ # Adam Community
30
+
31
+ Adam Community 是一个 Python 工具包,提供了 CLI 命令行工具和 Python 模块,用于解析和构建 Python 项目包。
32
+
33
+ ## 安装
34
+
35
+ ```bash
36
+ pip install -e .
37
+ ```
38
+
39
+ ## 使用方式
40
+
41
+ ### CLI 命令行
42
+
43
+ 查看帮助:
44
+ ```bash
45
+ adam-cli --help
46
+ ```
47
+
48
+ 初始化新项目:
49
+ ```bash
50
+ adam-cli init
51
+ ```
52
+
53
+ 解析 Python 文件生成 functions.json:
54
+ ```bash
55
+ adam-cli parse .
56
+ ```
57
+
58
+ 构建项目包:
59
+ ```bash
60
+ adam-cli build .
61
+ ```
62
+
63
+ 更新 CLI 到最新版本:
64
+ ```bash
65
+ adam-cli update
66
+ ```
67
+
68
+ ### Python 模块导入
69
+
70
+ ```python
71
+ from adam_community.cli.parser import parse_directory, parse_python_file
72
+ from adam_community.cli.build import build_package
73
+
74
+ # 解析目录下的 Python 文件
75
+ classes = parse_directory(Path("./"))
76
+
77
+ # 构建项目包
78
+ success, errors, zip_name = build_package(Path("./"))
79
+ ```
80
+
81
+ ## 功能特性
82
+
83
+ - **Python 文件解析**: 自动解析 Python 类和函数的文档字符串
84
+ - **JSON Schema 验证**: 将 Python 类型转换为 JSON Schema 并验证
85
+ - **项目构建**: 检查配置文件、文档文件并创建 zip 包
86
+ - **类型检查**: 支持多种 Python 类型注解格式
87
+ - **自动更新**: 智能检查和更新到最新版本,支持用户配置
88
+
89
+ ## 开发
90
+
91
+ 安装依赖:
92
+ ```bash
93
+ make install
94
+ ```
95
+
96
+ 运行测试:
97
+ ```bash
98
+ make test
99
+ ```
100
+
101
+ 构建包:
102
+ ```bash
103
+ make build
104
+ ```
@@ -0,0 +1,76 @@
1
+ # Adam Community
2
+
3
+ Adam Community 是一个 Python 工具包,提供了 CLI 命令行工具和 Python 模块,用于解析和构建 Python 项目包。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install -e .
9
+ ```
10
+
11
+ ## 使用方式
12
+
13
+ ### CLI 命令行
14
+
15
+ 查看帮助:
16
+ ```bash
17
+ adam-cli --help
18
+ ```
19
+
20
+ 初始化新项目:
21
+ ```bash
22
+ adam-cli init
23
+ ```
24
+
25
+ 解析 Python 文件生成 functions.json:
26
+ ```bash
27
+ adam-cli parse .
28
+ ```
29
+
30
+ 构建项目包:
31
+ ```bash
32
+ adam-cli build .
33
+ ```
34
+
35
+ 更新 CLI 到最新版本:
36
+ ```bash
37
+ adam-cli update
38
+ ```
39
+
40
+ ### Python 模块导入
41
+
42
+ ```python
43
+ from adam_community.cli.parser import parse_directory, parse_python_file
44
+ from adam_community.cli.build import build_package
45
+
46
+ # 解析目录下的 Python 文件
47
+ classes = parse_directory(Path("./"))
48
+
49
+ # 构建项目包
50
+ success, errors, zip_name = build_package(Path("./"))
51
+ ```
52
+
53
+ ## 功能特性
54
+
55
+ - **Python 文件解析**: 自动解析 Python 类和函数的文档字符串
56
+ - **JSON Schema 验证**: 将 Python 类型转换为 JSON Schema 并验证
57
+ - **项目构建**: 检查配置文件、文档文件并创建 zip 包
58
+ - **类型检查**: 支持多种 Python 类型注解格式
59
+ - **自动更新**: 智能检查和更新到最新版本,支持用户配置
60
+
61
+ ## 开发
62
+
63
+ 安装依赖:
64
+ ```bash
65
+ make install
66
+ ```
67
+
68
+ 运行测试:
69
+ ```bash
70
+ make test
71
+ ```
72
+
73
+ 构建包:
74
+ ```bash
75
+ make build
76
+ ```
@@ -1,6 +1,7 @@
1
1
  from .util import messageSend, knowledgeSearch, completionCreate, runCmd
2
2
  from .tool import Tool
3
3
  from .cli.parser import parse_python_file, parse_directory, convert_python_type_to_json_schema
4
+ from .__version__ import __version__
4
5
 
5
6
  __all__ = [
6
7
  'Tool',
@@ -0,0 +1 @@
1
+ __version__ = "1.0.3"
@@ -1,4 +1,5 @@
1
1
  import json
2
+ import sys
2
3
  import zipfile
3
4
  from pathlib import Path
4
5
  from typing import Tuple, List
@@ -14,29 +15,40 @@ def check_python_files(directory: Path) -> Tuple[bool, List[str]]:
14
15
  tree = Tree("📦 Python 文件检查")
15
16
  errors = []
16
17
  warnings = []
17
- functions = parse_directory(directory)
18
18
 
19
- tree.add(f"找到 {len(functions)} 个类定义")
19
+ # 解析 Python 文件,如果出现错误则退出
20
+ try:
21
+ functions = parse_directory(directory)
22
+ except Exception as e:
23
+ console.print(Panel.fit(
24
+ f"[bold red]❌ 解析 Python 文件时出错[/bold red]\n{str(e)}",
25
+ border_style="red"
26
+ ))
27
+ console.print("[red]构建失败,请检查并修复上述错误后重试。[/red]")
28
+ sys.exit(1)
29
+
30
+ # 统计信息
31
+ total_functions = len(functions)
32
+ functions_with_desc = 0
33
+ functions_with_params = 0
34
+
20
35
  for func in functions:
21
36
  func_info = func["function"]
22
37
 
23
38
  # 检查描述长度
24
39
  description = func_info.get("description")
25
40
  if description is None or not description:
26
- warning_msg = f"⚠️ {func_info['file']}: {func_info['name']} 没有描述"
27
- tree.add(warning_msg)
41
+ warning_msg = f"⚠️ {func_info['name']} 没有描述"
28
42
  warnings.append(warning_msg)
29
43
  elif len(description) > 1024:
30
- error_msg = f"❌ {func_info['file']}: {func_info['name']} 描述长度超过1024字符 ({len(description)})"
31
- tree.add(error_msg)
44
+ error_msg = f"❌ {func_info['name']} 描述长度超过1024字符 ({len(description)})"
32
45
  errors.append(error_msg)
33
46
  else:
34
- tree.add(f"✓ {func_info['file']}: {func_info['name']} 描述长度: {len(description)}")
47
+ functions_with_desc += 1
35
48
 
36
49
  # 检查参数定义
37
50
  if not func_info["parameters"]["properties"]:
38
- warning_msg = f"⚠️ {func_info['file']}: {func_info['name']} 没有参数定义"
39
- tree.add(warning_msg)
51
+ warning_msg = f"⚠️ {func_info['name']} 没有参数定义"
40
52
  warnings.append(warning_msg)
41
53
  else:
42
54
  # 检查参数类型是否都是有效的JSON Schema类型
@@ -49,33 +61,43 @@ def check_python_files(directory: Path) -> Tuple[bool, List[str]]:
49
61
 
50
62
  if param_errors:
51
63
  for param_error in param_errors:
52
- error_msg = f"❌ {func_info['file']}: {func_info['name']} - {param_error}"
53
- tree.add(error_msg)
64
+ error_msg = f"❌ {func_info['name']} - {param_error}"
54
65
  errors.append(error_msg)
55
66
  else:
56
- tree.add(f"✓ {func_info['file']}: {func_info['name']} 参数类型验证通过")
67
+ functions_with_params += 1
57
68
 
69
+ # 显示简化的统计信息
70
+ console.print(f"📦 Python 文件检查: 找到 {total_functions} 个类定义")
71
+ console.print(f" ✓ 描述完整: {functions_with_desc}/{total_functions}")
72
+ console.print(f" ✓ 参数完整: {functions_with_params}/{total_functions}")
73
+
74
+ # 显示错误和警告
58
75
  if errors:
59
- tree.add("❌ 检查未通过")
60
- else:
61
- tree.add("✅ 检查通过")
76
+ console.print(f" {len(errors)} 个错误:")
77
+ for error in errors[:5]: # 只显示前5个错误
78
+ console.print(f" {error}")
79
+ if len(errors) > 5:
80
+ console.print(f" ... 还有 {len(errors) - 5} 个错误")
62
81
 
63
- # 显示警告信息
64
82
  if warnings:
65
- tree.add(f"⚠️ 发现 {len(warnings)} 个警告(不影响构建)")
66
-
67
- console.print(tree)
83
+ console.print(f" ⚠️ {len(warnings)} 个警告 (不影响构建)")
84
+ if len(warnings) <= 3:
85
+ for warning in warnings:
86
+ console.print(f" {warning}")
87
+ else:
88
+ console.print(f" {warnings[0]}")
89
+ console.print(f" ... 还有 {len(warnings) - 1} 个警告")
68
90
  return len(errors) == 0, errors
69
91
 
70
92
  def check_configuration(directory: Path) -> Tuple[bool, List[str]]:
71
93
  """检查 configure.json 文件"""
72
- tree = Tree("📄 配置文件检查")
73
94
  errors = []
74
95
  config_path = directory / "config" / "configure.json"
75
96
 
97
+ console.print("📄 配置文件检查:")
98
+
76
99
  if not config_path.exists():
77
- tree.add("❌ 未找到 configure.json 文件")
78
- console.print(tree)
100
+ console.print(" ❌ 未找到 configure.json 文件")
79
101
  return False, ["configure.json 文件不存在"]
80
102
 
81
103
  try:
@@ -83,28 +105,30 @@ def check_configuration(directory: Path) -> Tuple[bool, List[str]]:
83
105
  config = json.load(f)
84
106
 
85
107
  required_fields = ["name", "version", "display_name"]
108
+ valid_fields = 0
109
+
86
110
  for field in required_fields:
87
111
  if field not in config:
88
112
  errors.append(f"configure.json 缺少必要字段: {field}")
89
- tree.add(f"❌ 缺少字段: {field}")
90
113
  else:
91
- tree.add(f"✓ {field}: {config[field]}")
114
+ valid_fields += 1
115
+
116
+ console.print(f" ✓ 字段完整: {valid_fields}/{len(required_fields)}")
92
117
 
93
118
  if errors:
94
- tree.add("❌ 检查未通过")
119
+ console.print(f" {len(errors)} 个错误:")
120
+ for error in errors:
121
+ console.print(f" {error}")
95
122
  else:
96
- tree.add(" 检查通过")
123
+ console.print(f" 包信息: {config['name']} v{config['version']}")
97
124
 
98
- console.print(tree)
99
125
  return len(errors) == 0, errors
100
126
  except json.JSONDecodeError:
101
- tree.add("❌ 配置文件格式错误")
102
- console.print(tree)
127
+ console.print(" ❌ 配置文件格式错误")
103
128
  return False, ["configure.json 文件格式错误"]
104
129
 
105
130
  def check_markdown_files(directory: Path) -> Tuple[bool, List[str]]:
106
131
  """检查必要的 Markdown 文件"""
107
- tree = Tree("📑 Markdown 文件检查")
108
132
  errors = []
109
133
 
110
134
  # 先读取配置文件中的 type 字段
@@ -133,88 +157,88 @@ def check_markdown_files(directory: Path) -> Tuple[bool, List[str]]:
133
157
  "long_description.md"
134
158
  ]
135
159
 
136
- tree.add(f"检查类型: {config_type}")
160
+ console.print(f"📑 文档文件检查 ({config_type} 类型):")
137
161
 
162
+ valid_files = 0
138
163
  for file in required_files:
139
164
  file_path = directory / "config" / file
140
165
  if not file_path.exists():
141
166
  errors.append(f"缺少必要文件: {file}")
142
- tree.add(f"❌ {file}")
143
167
  else:
144
168
  # 对于 input.json,额外检查 JSON 格式
145
169
  if file == "input.json":
146
170
  try:
147
171
  with open(file_path, 'r', encoding='utf-8') as f:
148
172
  json.load(f)
149
- tree.add(f"✓ {file} (JSON 格式正确)")
173
+ valid_files += 1
150
174
  except json.JSONDecodeError:
151
175
  errors.append(f"{file} JSON 格式错误")
152
- tree.add(f"❌ {file} (JSON 格式错误)")
153
176
  else:
154
- tree.add(f"✓ {file}")
177
+ valid_files += 1
178
+
179
+ console.print(f" ✓ 文件完整: {valid_files}/{len(required_files)}")
155
180
 
156
181
  if errors:
157
- tree.add("❌ 检查未通过")
158
- else:
159
- tree.add("✅ 检查通过")
182
+ console.print(f" {len(errors)} 个错误:")
183
+ for error in errors:
184
+ console.print(f" {error}")
160
185
 
161
- console.print(tree)
162
186
  return len(errors) == 0, errors
163
187
 
164
188
  def create_zip_package(directory: Path) -> str:
165
189
  """创建 zip 包"""
166
- tree = Tree("📦 创建压缩包")
167
190
  with open(directory / "config" / "configure.json", 'r', encoding='utf-8') as f:
168
191
  config = json.load(f)
169
192
 
170
193
  zip_name = f"{config['name']}_{config['version']}.zip"
171
194
  zip_path = directory / zip_name
172
195
 
173
- tree.add(f"包名: {zip_name}")
196
+ console.print("📦 创建压缩包:")
197
+ console.print(f" 包名: {zip_name}")
174
198
 
175
199
  # 获取配置类型
176
200
  config_type = config.get("type", "agent")
201
+ file_count = 0
177
202
 
178
203
  with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
179
204
  # 添加所有 Python 文件
180
- py_files = list(directory.rglob('*.py'))
181
- py_tree = tree.add("Python 文件")
205
+ py_files = [f for f in directory.rglob('*.py') if not f.name.startswith('_')]
182
206
  for py_file in py_files:
183
- if not py_file.name.startswith('_'):
184
- zipf.write(py_file, py_file.relative_to(directory))
185
- py_tree.add(f"+ {py_file.relative_to(directory)}")
207
+ zipf.write(py_file, py_file.relative_to(directory))
208
+ file_count += 1
186
209
 
187
210
  # 添加配置文件
188
- config_tree = tree.add("配置文件")
189
211
  zipf.write(directory / "config" / "configure.json", "config/configure.json")
190
- config_tree.add("+ config/configure.json")
212
+ file_count += 1
191
213
 
192
214
  # 添加 demos 目录
193
- demos_tree = tree.add("Demos 文件")
194
215
  demos_dir = directory / "demos"
216
+ demos_files = 0
195
217
  if demos_dir.exists() and demos_dir.is_dir():
196
218
  for demos_file in demos_dir.rglob('*'):
197
219
  if demos_file.is_file():
198
220
  zipf.write(demos_file, demos_file.relative_to(directory))
199
- demos_tree.add(f"+ {demos_file.relative_to(directory)}")
221
+ file_count += 1
222
+ demos_files += 1
200
223
 
201
224
  # 根据类型添加不同的文件
202
- md_tree = tree.add("其他文件")
203
225
  if config_type == "kit":
204
- # kit 类型需要添加的文件
205
226
  other_files = ["long_description.md", "input.json"]
206
227
  else:
207
- # agent 类型需要添加的文件
208
228
  other_files = ["initial_assistant_message.md", "initial_system_prompt.md", "long_description.md"]
209
229
 
210
230
  for file in other_files:
211
231
  file_path = directory / "config" / file
212
232
  if file_path.exists():
213
233
  zipf.write(file_path, f"config/{file}")
214
- md_tree.add(f"+ config/{file}")
234
+ file_count += 1
235
+
236
+ console.print(f" ✓ Python 文件: {len(py_files)} 个")
237
+ console.print(f" ✓ 配置文件: 1 个")
238
+ if demos_files > 0:
239
+ console.print(f" ✓ 演示文件: {demos_files} 个")
240
+ console.print(f" ✓ 总计: {file_count} 个文件")
215
241
 
216
- tree.add("✅ 压缩包创建完成")
217
- console.print(tree)
218
242
  return zip_name
219
243
 
220
244
  def build_package(directory: Path) -> Tuple[bool, List[str], str]:
@@ -236,18 +260,21 @@ def build_package(directory: Path) -> Tuple[bool, List[str], str]:
236
260
  if not py_passed:
237
261
  all_passed = False
238
262
  all_errors.extend(py_errors)
263
+ console.print() # 添加空行
239
264
 
240
265
  # 2. 检查配置文件
241
266
  config_passed, config_errors = check_configuration(directory)
242
267
  if not config_passed:
243
268
  all_passed = False
244
269
  all_errors.extend(config_errors)
270
+ console.print() # 添加空行
245
271
 
246
272
  # 3. 检查 Markdown 文件
247
273
  md_passed, md_errors = check_markdown_files(directory)
248
274
  if not md_passed:
249
275
  all_passed = False
250
276
  all_errors.extend(md_errors)
277
+ console.print() # 添加空行
251
278
 
252
279
  # 如果所有检查都通过,创建 zip 包
253
280
  zip_name = ""
@@ -262,7 +289,8 @@ def build_package(directory: Path) -> Tuple[bool, List[str], str]:
262
289
  ))
263
290
  else:
264
291
  console.print(Panel.fit(
265
- "[bold red]❌ 构建失败![/bold red]\n" + "\n".join(all_errors),
292
+ f"[bold red]❌ 构建失败![/bold red]\n"
293
+ f"共发现 {len(all_errors)} 个错误,请修复后重试。",
266
294
  border_style="red"
267
295
  ))
268
296
 
@@ -4,11 +4,13 @@ from pathlib import Path
4
4
  from .parser import parse_directory
5
5
  from .build import build_package
6
6
  from .init import init
7
+ from .updater import check_and_notify_update, update_cli, set_update_disabled
7
8
 
8
9
  @click.group()
9
10
  def cli():
10
11
  """Adam Community CLI 工具"""
11
- pass
12
+ # 检查更新(静默执行,不影响正常功能)
13
+ check_and_notify_update()
12
14
 
13
15
  @cli.command()
14
16
  @click.argument('directory', type=click.Path(exists=True, file_okay=False, dir_okay=True), default='.')
@@ -41,6 +43,33 @@ def build(directory):
41
43
  click.echo(f"- {error}")
42
44
  raise click.Abort()
43
45
 
46
+ @cli.command()
47
+ def update():
48
+ """更新 CLI 到最新版本"""
49
+ if update_cli():
50
+ click.echo("\n🎉 更新完成!重新运行命令以使用新版本。")
51
+ else:
52
+ click.echo("\n❌ 更新失败,请手动更新或检查网络连接。")
53
+ click.echo("手动更新命令:pip install --upgrade adam-community")
54
+
55
+ @cli.command()
56
+ @click.option('--disable-update-check', is_flag=True, help='禁用自动更新检查')
57
+ @click.option('--enable-update-check', is_flag=True, help='启用自动更新检查')
58
+ def config(disable_update_check, enable_update_check):
59
+ """配置 CLI 设置"""
60
+ if disable_update_check and enable_update_check:
61
+ click.echo("错误:不能同时启用和禁用更新检查")
62
+ return
63
+
64
+ if disable_update_check:
65
+ set_update_disabled(True)
66
+ click.echo("✅ 已禁用自动更新检查")
67
+ elif enable_update_check:
68
+ set_update_disabled(False)
69
+ click.echo("✅ 已启用自动更新检查")
70
+ else:
71
+ click.echo("请使用 --disable-update-check 或 --enable-update-check 选项")
72
+
44
73
  # 添加 init 命令
45
74
  cli.add_command(init)
46
75
 
@@ -2,6 +2,7 @@ import ast
2
2
  from pathlib import Path
3
3
  from typing import List, Dict, Any
4
4
  from docstring_parser import parse as dsp
5
+ import jsonschema
5
6
 
6
7
  def convert_python_type_to_json_schema(python_type: str) -> Dict[str, Any]:
7
8
  """将 Python 类型转换为 JSON Schema 类型
@@ -13,7 +14,7 @@ def convert_python_type_to_json_schema(python_type: str) -> Dict[str, Any]:
13
14
  Dict[str, Any]: JSON Schema 类型定义
14
15
 
15
16
  Raises:
16
- ValueError: 当无法转换类型时抛出异常
17
+ ValueError: 当无法转换类型或生成的 schema 不符合规范时抛出异常
17
18
  """
18
19
  python_type = python_type.lower().strip()
19
20
 
@@ -40,7 +41,13 @@ def convert_python_type_to_json_schema(python_type: str) -> Dict[str, Any]:
40
41
 
41
42
  # 处理基本类型
42
43
  if python_type in basic_types:
43
- return {"type": basic_types[python_type]}
44
+ schema_type = basic_types[python_type]
45
+ if schema_type == "array":
46
+ # 对于没有指定元素类型的数组,应该报错要求明确指定
47
+ raise ValueError(f"数组类型 '{python_type}' 缺少元素类型定义,请使用 List[ElementType] 格式明确指定元素类型")
48
+ else:
49
+ schema = {"type": schema_type}
50
+ return _create_and_validate_schema(schema, python_type)
44
51
 
45
52
  # 处理 Literal[T1, T2, ...] 格式
46
53
  if python_type.startswith('literal[') and python_type.endswith(']'):
@@ -50,22 +57,22 @@ def convert_python_type_to_json_schema(python_type: str) -> Dict[str, Any]:
50
57
  # 尝试推断类型
51
58
  if all(v.isdigit() or (v.startswith('-') and v[1:].isdigit()) for v in values):
52
59
  # 所有值都是整数
53
- return {
60
+ return _create_and_validate_schema({
54
61
  "type": "integer",
55
62
  "enum": [int(v) for v in values]
56
- }
63
+ }, python_type)
57
64
  elif all(v.replace('.', '').replace('-', '').isdigit() for v in values):
58
65
  # 所有值都是数字
59
- return {
66
+ return _create_and_validate_schema({
60
67
  "type": "number",
61
68
  "enum": [float(v) for v in values]
62
- }
69
+ }, python_type)
63
70
  else:
64
71
  # 字符串类型
65
- return {
72
+ return _create_and_validate_schema({
66
73
  "type": "string",
67
74
  "enum": values
68
- }
75
+ }, python_type)
69
76
 
70
77
  # 处理 Union[T1, T2, ...] 或 T1 | T2 格式
71
78
  if python_type.startswith('union[') and python_type.endswith(']'):
@@ -83,12 +90,12 @@ def convert_python_type_to_json_schema(python_type: str) -> Dict[str, Any]:
83
90
  inner_type = python_type[9:-1].strip()
84
91
  try:
85
92
  inner_schema = convert_python_type_to_json_schema(inner_type)
86
- return {
93
+ return _create_and_validate_schema({
87
94
  "oneOf": [
88
95
  inner_schema,
89
96
  {"type": "null"}
90
97
  ]
91
- }
98
+ }, python_type)
92
99
  except ValueError as e:
93
100
  raise ValueError(f"无法转换Optional类型 '{python_type}': {str(e)}")
94
101
 
@@ -97,10 +104,10 @@ def convert_python_type_to_json_schema(python_type: str) -> Dict[str, Any]:
97
104
  inner_type = python_type[5:-1] # 提取 List[ 和 ] 之间的内容
98
105
  try:
99
106
  items_schema = convert_python_type_to_json_schema(inner_type)
100
- return {
107
+ return _create_and_validate_schema({
101
108
  "type": "array",
102
109
  "items": items_schema
103
- }
110
+ }, python_type)
104
111
  except ValueError as e:
105
112
  raise ValueError(f"无法转换列表元素类型 '{inner_type}': {str(e)}")
106
113
 
@@ -109,10 +116,10 @@ def convert_python_type_to_json_schema(python_type: str) -> Dict[str, Any]:
109
116
  inner_type = python_type[5:-1]
110
117
  try:
111
118
  items_schema = convert_python_type_to_json_schema(inner_type)
112
- return {
119
+ return _create_and_validate_schema({
113
120
  "type": "array",
114
121
  "items": items_schema
115
- }
122
+ }, python_type)
116
123
  except ValueError as e:
117
124
  raise ValueError(f"无法转换列表元素类型 '{inner_type}': {str(e)}")
118
125
 
@@ -128,29 +135,90 @@ def convert_python_type_to_json_schema(python_type: str) -> Dict[str, Any]:
128
135
  try:
129
136
  key_schema = convert_python_type_to_json_schema(key_type)
130
137
  value_schema = convert_python_type_to_json_schema(value_type)
131
- return {
138
+ return _create_and_validate_schema({
132
139
  "type": "object",
133
140
  "additionalProperties": value_schema
134
- }
141
+ }, python_type)
135
142
  except ValueError as e:
136
143
  raise ValueError(f"无法转换字典类型 '{python_type}': {str(e)}")
137
144
  else:
138
145
  # 只有值类型的情况
139
146
  try:
140
147
  value_schema = convert_python_type_to_json_schema(content.strip())
141
- return {
148
+ return _create_and_validate_schema({
142
149
  "type": "object",
143
150
  "additionalProperties": value_schema
144
- }
151
+ }, python_type)
145
152
  except ValueError as e:
146
153
  raise ValueError(f"无法转换字典值类型 '{content}': {str(e)}")
147
154
 
148
155
  # 处理枚举类型
149
156
  if python_type == 'enum':
150
- return {"type": "string"}
157
+ return _create_and_validate_schema({"type": "string"}, python_type)
158
+
159
+ # 如果无法识别,返回基本的 object 类型
160
+ schema = {"type": "object"}
161
+
162
+ # 验证生成的 schema
163
+ try:
164
+ validate_json_schema(schema)
165
+ return schema
166
+ except ValueError as e:
167
+ raise ValueError(f"生成的 JSON Schema 不符合规范 (类型: '{python_type}'): {str(e)}")
168
+
169
+ def _create_and_validate_schema(schema: Dict[str, Any], python_type: str) -> Dict[str, Any]:
170
+ """创建并验证 JSON Schema
151
171
 
152
- # 如果无法识别,抛出异常
153
- raise ValueError(f"无法转换的Python类型: '{python_type}'")
172
+ Args:
173
+ schema: 要验证的 schema
174
+ python_type: 原始 Python 类型(用于错误信息)
175
+
176
+ Returns:
177
+ Dict[str, Any]: 验证通过的 schema
178
+
179
+ Raises:
180
+ ValueError: 当 schema 不符合规范时抛出异常
181
+ """
182
+ try:
183
+ validate_json_schema(schema)
184
+ return schema
185
+ except ValueError as e:
186
+ raise ValueError(f"生成的 JSON Schema 不符合规范 (类型: '{python_type}'): {str(e)}")
187
+
188
+ def validate_json_schema(schema: Dict[str, Any], context: str = "") -> None:
189
+ """验证生成的 JSON Schema 是否符合规范
190
+
191
+ Args:
192
+ schema: 要验证的 JSON Schema
193
+ context: 上下文信息,用于错误报告
194
+
195
+ Raises:
196
+ ValueError: 当 schema 不符合规范时抛出异常
197
+ """
198
+ try:
199
+ # 使用 JSON Schema Draft 7 验证器
200
+ jsonschema.Draft7Validator.check_schema(schema)
201
+
202
+ # 额外的自定义验证
203
+ if schema.get("type") == "array" and "items" not in schema:
204
+ raise ValueError(f"array schema missing items{f' in {context}' if context else ''}")
205
+
206
+ if schema.get("type") == "object":
207
+ if "properties" in schema:
208
+ for prop_name, prop_schema in schema["properties"].items():
209
+ validate_json_schema(prop_schema, f"{context}.{prop_name}" if context else prop_name)
210
+ if "additionalProperties" in schema and isinstance(schema["additionalProperties"], dict):
211
+ validate_json_schema(schema["additionalProperties"], f"{context}.additionalProperties" if context else "additionalProperties")
212
+
213
+ if "oneOf" in schema:
214
+ for i, sub_schema in enumerate(schema["oneOf"]):
215
+ validate_json_schema(sub_schema, f"{context}.oneOf[{i}]" if context else f"oneOf[{i}]")
216
+
217
+ if "items" in schema:
218
+ validate_json_schema(schema["items"], f"{context}.items" if context else "items")
219
+
220
+ except jsonschema.SchemaError as e:
221
+ raise ValueError(f"Invalid JSON Schema{f' in {context}' if context else ''}: {str(e)}")
154
222
 
155
223
  def convert_union_types(types: List[str]) -> Dict[str, Any]:
156
224
  """转换联合类型为 JSON Schema
@@ -174,7 +242,9 @@ def convert_union_types(types: List[str]) -> Dict[str, Any]:
174
242
  if len(schemas) == 1:
175
243
  return schemas[0]
176
244
  else:
177
- return {"oneOf": schemas}
245
+ result_schema = {"oneOf": schemas}
246
+ validate_json_schema(result_schema)
247
+ return result_schema
178
248
 
179
249
  def validate_description_length(description: str, function_name: str, file_path: str) -> None:
180
250
  """验证函数描述长度
@@ -285,6 +355,15 @@ def parse_python_file(file_path: Path) -> List[Dict[str, Any]]:
285
355
  f"参数 '{p.arg_name}' 的类型转换失败: {str(e)}"
286
356
  )
287
357
 
358
+ # 验证最终的 parameters schema
359
+ try:
360
+ validate_json_schema(parameters, f"function '{node.name}' parameters")
361
+ except ValueError as e:
362
+ raise ValueError(
363
+ f"在文件 '{file_path}' 的函数 '{node.name}' 中,"
364
+ f"生成的参数 schema 不符合规范: {str(e)}"
365
+ )
366
+
288
367
  class_info = {
289
368
  "function": {
290
369
  "name": f"{file_path.stem}.{node.name}",
@@ -305,8 +384,8 @@ def parse_python_file(file_path: Path) -> List[Dict[str, Any]]:
305
384
 
306
385
  return classes
307
386
  except Exception as e:
308
- print(f"解析文件 {file_path} 时出错: {str(e)}")
309
- return []
387
+ print(f"解析文件 {file_path.name} 时出错: {str(e)}")
388
+ raise # 重新抛出异常,让上层处理
310
389
 
311
390
  def parse_directory(directory: Path) -> List[Dict[str, Any]]:
312
391
  """解析目录下的所有 Python 文件
@@ -0,0 +1,201 @@
1
+ import json
2
+ import subprocess
3
+ import sys
4
+ from datetime import datetime, timedelta
5
+ from pathlib import Path
6
+ from typing import Optional, Tuple
7
+ import requests
8
+ from packaging import version
9
+ import click
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+
13
+ console = Console()
14
+
15
+ def get_cache_dir() -> Path:
16
+ """获取缓存目录"""
17
+ cache_dir = Path.home() / ".adam_cli" / "cache"
18
+ cache_dir.mkdir(parents=True, exist_ok=True)
19
+ return cache_dir
20
+
21
+ def get_current_version() -> str:
22
+ """获取当前版本"""
23
+ try:
24
+ # 尝试从 setup.py 或 __version__ 获取版本
25
+ from adam_community import __version__
26
+ return __version__
27
+ except ImportError:
28
+ # 如果无法导入,尝试从 pip 获取
29
+ try:
30
+ result = subprocess.run(
31
+ [sys.executable, "-m", "pip", "show", "adam-community"],
32
+ capture_output=True, text=True, timeout=10
33
+ )
34
+ if result.returncode == 0:
35
+ for line in result.stdout.split('\n'):
36
+ if line.startswith('Version:'):
37
+ return line.split(':', 1)[1].strip()
38
+ except:
39
+ pass
40
+ return "unknown"
41
+
42
+ def get_latest_version_from_pypi() -> Optional[str]:
43
+ """从 PyPI 获取最新版本"""
44
+ try:
45
+ response = requests.get(
46
+ "https://pypi.org/pypi/adam-community/json",
47
+ timeout=5
48
+ )
49
+ if response.status_code == 200:
50
+ data = response.json()
51
+ return data['info']['version']
52
+ except:
53
+ pass
54
+ return None
55
+
56
+ def should_check_update() -> bool:
57
+ """检查是否需要检查更新(基于缓存时间)"""
58
+ cache_file = get_cache_dir() / "last_update_check.json"
59
+
60
+ if not cache_file.exists():
61
+ return True
62
+
63
+ try:
64
+ with open(cache_file, 'r') as f:
65
+ data = json.load(f)
66
+
67
+ last_check = datetime.fromisoformat(data['last_check'])
68
+ # 24小时检查一次
69
+ return datetime.now() - last_check > timedelta(hours=24)
70
+ except:
71
+ return True
72
+
73
+ def save_check_time():
74
+ """保存检查时间"""
75
+ cache_file = get_cache_dir() / "last_update_check.json"
76
+
77
+ try:
78
+ with open(cache_file, 'w') as f:
79
+ json.dump({
80
+ 'last_check': datetime.now().isoformat()
81
+ }, f)
82
+ except:
83
+ pass
84
+
85
+ def is_update_disabled() -> bool:
86
+ """检查是否禁用了自动更新检查"""
87
+ config_file = get_cache_dir() / "config.json"
88
+
89
+ if not config_file.exists():
90
+ return False
91
+
92
+ try:
93
+ with open(config_file, 'r') as f:
94
+ config = json.load(f)
95
+ return config.get('disable_update_check', False)
96
+ except:
97
+ return False
98
+
99
+ def set_update_disabled(disabled: bool):
100
+ """设置是否禁用自动更新检查"""
101
+ config_file = get_cache_dir() / "config.json"
102
+
103
+ try:
104
+ config = {}
105
+ if config_file.exists():
106
+ with open(config_file, 'r') as f:
107
+ config = json.load(f)
108
+
109
+ config['disable_update_check'] = disabled
110
+
111
+ with open(config_file, 'w') as f:
112
+ json.dump(config, f, indent=2)
113
+ except:
114
+ pass
115
+
116
+ def check_for_update() -> Tuple[bool, Optional[str], Optional[str]]:
117
+ """检查更新,返回(有更新, 当前版本, 最新版本)"""
118
+ if is_update_disabled():
119
+ return False, None, None
120
+
121
+ if not should_check_update():
122
+ return False, None, None
123
+
124
+ current_ver = get_current_version()
125
+ latest_ver = get_latest_version_from_pypi()
126
+
127
+ save_check_time()
128
+
129
+ if current_ver == "unknown" or latest_ver is None:
130
+ return False, current_ver, latest_ver
131
+
132
+ try:
133
+ has_update = version.parse(latest_ver) > version.parse(current_ver)
134
+ return has_update, current_ver, latest_ver
135
+ except:
136
+ return False, current_ver, latest_ver
137
+
138
+ def show_update_notification(current_ver: str, latest_ver: str):
139
+ """显示更新通知"""
140
+ console.print()
141
+ console.print(Panel.fit(
142
+ f"[yellow]📦 发现新版本![/yellow]\n"
143
+ f"当前版本: [red]{current_ver}[/red]\n"
144
+ f"最新版本: [green]{latest_ver}[/green]\n\n"
145
+ f"[dim]运行以下命令更新:[/dim]\n"
146
+ f"[cyan]adam-cli update[/cyan]\n\n"
147
+ f"[dim]或运行以下命令禁用更新检查:[/dim]\n"
148
+ f"[cyan]adam-cli config --disable-update-check[/cyan]",
149
+ border_style="yellow",
150
+ title="[yellow]🚀 更新提醒[/yellow]"
151
+ ))
152
+ console.print()
153
+
154
+ def update_cli():
155
+ """更新 CLI 到最新版本"""
156
+ console.print("🔍 检查最新版本...")
157
+
158
+ latest_ver = get_latest_version_from_pypi()
159
+ if latest_ver is None:
160
+ console.print("[red]❌ 无法获取最新版本信息,请检查网络连接[/red]")
161
+ return False
162
+
163
+ current_ver = get_current_version()
164
+
165
+ if current_ver != "unknown":
166
+ try:
167
+ if version.parse(current_ver) >= version.parse(latest_ver):
168
+ console.print(f"[green]✅ 已是最新版本 {current_ver}[/green]")
169
+ return True
170
+ except:
171
+ pass
172
+
173
+ console.print(f"📦 开始更新到版本 {latest_ver}...")
174
+
175
+ try:
176
+ # 使用 pip 更新
177
+ result = subprocess.run([
178
+ sys.executable, "-m", "pip", "install", "--upgrade", "adam-community"
179
+ ], capture_output=True, text=True)
180
+
181
+ if result.returncode == 0:
182
+ console.print(f"[green]✅ 更新成功![/green]")
183
+ console.print(f"[green]当前版本: {latest_ver}[/green]")
184
+ return True
185
+ else:
186
+ console.print(f"[red]❌ 更新失败:[/red]")
187
+ console.print(f"[red]{result.stderr}[/red]")
188
+ return False
189
+ except Exception as e:
190
+ console.print(f"[red]❌ 更新过程中出错:{str(e)}[/red]")
191
+ return False
192
+
193
+ def check_and_notify_update():
194
+ """检查并通知更新(在 CLI 启动时调用)"""
195
+ try:
196
+ has_update, current_ver, latest_ver = check_for_update()
197
+ if has_update and current_ver and latest_ver:
198
+ show_update_notification(current_ver, latest_ver)
199
+ except:
200
+ # 静默处理错误,不影响正常功能
201
+ pass
@@ -0,0 +1,104 @@
1
+ Metadata-Version: 2.2
2
+ Name: adam_community
3
+ Version: 1.0.3
4
+ Summary: Adam Community Tools and Utilities
5
+ Home-page: https://github.com/yourusername/adam-community
6
+ Author: Adam Community
7
+ Author-email: admin@sidereus-ai.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.8
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: requests>=2.31.0
14
+ Requires-Dist: click>=8.0.0
15
+ Requires-Dist: docstring-parser>=0.15
16
+ Requires-Dist: rich>=13.0.0
17
+ Requires-Dist: packaging>=21.0
18
+ Requires-Dist: jsonschema>=4.0.0
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: classifier
22
+ Dynamic: description
23
+ Dynamic: description-content-type
24
+ Dynamic: home-page
25
+ Dynamic: requires-dist
26
+ Dynamic: requires-python
27
+ Dynamic: summary
28
+
29
+ # Adam Community
30
+
31
+ Adam Community 是一个 Python 工具包,提供了 CLI 命令行工具和 Python 模块,用于解析和构建 Python 项目包。
32
+
33
+ ## 安装
34
+
35
+ ```bash
36
+ pip install -e .
37
+ ```
38
+
39
+ ## 使用方式
40
+
41
+ ### CLI 命令行
42
+
43
+ 查看帮助:
44
+ ```bash
45
+ adam-cli --help
46
+ ```
47
+
48
+ 初始化新项目:
49
+ ```bash
50
+ adam-cli init
51
+ ```
52
+
53
+ 解析 Python 文件生成 functions.json:
54
+ ```bash
55
+ adam-cli parse .
56
+ ```
57
+
58
+ 构建项目包:
59
+ ```bash
60
+ adam-cli build .
61
+ ```
62
+
63
+ 更新 CLI 到最新版本:
64
+ ```bash
65
+ adam-cli update
66
+ ```
67
+
68
+ ### Python 模块导入
69
+
70
+ ```python
71
+ from adam_community.cli.parser import parse_directory, parse_python_file
72
+ from adam_community.cli.build import build_package
73
+
74
+ # 解析目录下的 Python 文件
75
+ classes = parse_directory(Path("./"))
76
+
77
+ # 构建项目包
78
+ success, errors, zip_name = build_package(Path("./"))
79
+ ```
80
+
81
+ ## 功能特性
82
+
83
+ - **Python 文件解析**: 自动解析 Python 类和函数的文档字符串
84
+ - **JSON Schema 验证**: 将 Python 类型转换为 JSON Schema 并验证
85
+ - **项目构建**: 检查配置文件、文档文件并创建 zip 包
86
+ - **类型检查**: 支持多种 Python 类型注解格式
87
+ - **自动更新**: 智能检查和更新到最新版本,支持用户配置
88
+
89
+ ## 开发
90
+
91
+ 安装依赖:
92
+ ```bash
93
+ make install
94
+ ```
95
+
96
+ 运行测试:
97
+ ```bash
98
+ make test
99
+ ```
100
+
101
+ 构建包:
102
+ ```bash
103
+ make build
104
+ ```
@@ -1,6 +1,7 @@
1
1
  README.md
2
2
  setup.py
3
3
  adam_community/__init__.py
4
+ adam_community/__version__.py
4
5
  adam_community/tool.py
5
6
  adam_community/util.py
6
7
  adam_community.egg-info/PKG-INFO
@@ -14,5 +15,6 @@ adam_community/cli/build.py
14
15
  adam_community/cli/cli.py
15
16
  adam_community/cli/init.py
16
17
  adam_community/cli/parser.py
18
+ adam_community/cli/updater.py
17
19
  adam_community/cli/templates/__init__.py
18
20
  test/test_util_tool.py
@@ -2,3 +2,5 @@ requests>=2.31.0
2
2
  click>=8.0.0
3
3
  docstring-parser>=0.15
4
4
  rich>=13.0.0
5
+ packaging>=21.0
6
+ jsonschema>=4.0.0
@@ -1,15 +1,24 @@
1
1
  from setuptools import setup, find_packages
2
2
  import os
3
3
 
4
+ # 读取版本号
5
+ def get_version():
6
+ version = {}
7
+ with open(os.path.join("adam_community", "__version__.py")) as fp:
8
+ exec(fp.read(), version)
9
+ return version['__version__']
10
+
4
11
  setup(
5
12
  name="adam_community",
6
- version="1.0.1",
13
+ version=get_version(),
7
14
  packages=find_packages(),
8
15
  install_requires=[
9
16
  "requests>=2.31.0",
10
17
  "click>=8.0.0",
11
18
  "docstring-parser>=0.15",
12
19
  "rich>=13.0.0",
20
+ "packaging>=21.0",
21
+ "jsonschema>=4.0.0",
13
22
  ],
14
23
  entry_points={
15
24
  'console_scripts': [
@@ -1,53 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: adam_community
3
- Version: 1.0.1
4
- Summary: Adam Community Tools and Utilities
5
- Home-page: https://github.com/yourusername/adam-community
6
- Author: Adam Community
7
- Author-email: admin@sidereus-ai.com
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.8
12
- Description-Content-Type: text/markdown
13
- Requires-Dist: requests>=2.31.0
14
- Requires-Dist: click>=8.0.0
15
- Requires-Dist: docstring-parser>=0.15
16
- Requires-Dist: rich>=13.0.0
17
- Dynamic: author
18
- Dynamic: author-email
19
- Dynamic: classifier
20
- Dynamic: description
21
- Dynamic: description-content-type
22
- Dynamic: home-page
23
- Dynamic: requires-dist
24
- Dynamic: requires-python
25
- Dynamic: summary
26
-
27
- # Adam Community
28
-
29
- Adam Community 是一个 Python 工具包,提供了一系列实用工具和功能,用于与 Adam 社区相关的开发工作。
30
-
31
- 安装依赖:
32
- ```bash
33
- make install
34
- ```
35
-
36
-
37
- ## 使用方法
38
-
39
- 安装完成后,您可以在 Python 代码中导入并使用该包:
40
-
41
- ```python
42
- from adam_community import tool
43
- from adam_community import util
44
-
45
- # 使用相关功能
46
- ```
47
-
48
- ## 开发
49
-
50
- 运行测试:
51
- ```bash
52
- make test
53
- ```
@@ -1,27 +0,0 @@
1
- # Adam Community
2
-
3
- Adam Community 是一个 Python 工具包,提供了一系列实用工具和功能,用于与 Adam 社区相关的开发工作。
4
-
5
- 安装依赖:
6
- ```bash
7
- make install
8
- ```
9
-
10
-
11
- ## 使用方法
12
-
13
- 安装完成后,您可以在 Python 代码中导入并使用该包:
14
-
15
- ```python
16
- from adam_community import tool
17
- from adam_community import util
18
-
19
- # 使用相关功能
20
- ```
21
-
22
- ## 开发
23
-
24
- 运行测试:
25
- ```bash
26
- make test
27
- ```
@@ -1,53 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: adam_community
3
- Version: 1.0.1
4
- Summary: Adam Community Tools and Utilities
5
- Home-page: https://github.com/yourusername/adam-community
6
- Author: Adam Community
7
- Author-email: admin@sidereus-ai.com
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.8
12
- Description-Content-Type: text/markdown
13
- Requires-Dist: requests>=2.31.0
14
- Requires-Dist: click>=8.0.0
15
- Requires-Dist: docstring-parser>=0.15
16
- Requires-Dist: rich>=13.0.0
17
- Dynamic: author
18
- Dynamic: author-email
19
- Dynamic: classifier
20
- Dynamic: description
21
- Dynamic: description-content-type
22
- Dynamic: home-page
23
- Dynamic: requires-dist
24
- Dynamic: requires-python
25
- Dynamic: summary
26
-
27
- # Adam Community
28
-
29
- Adam Community 是一个 Python 工具包,提供了一系列实用工具和功能,用于与 Adam 社区相关的开发工作。
30
-
31
- 安装依赖:
32
- ```bash
33
- make install
34
- ```
35
-
36
-
37
- ## 使用方法
38
-
39
- 安装完成后,您可以在 Python 代码中导入并使用该包:
40
-
41
- ```python
42
- from adam_community import tool
43
- from adam_community import util
44
-
45
- # 使用相关功能
46
- ```
47
-
48
- ## 开发
49
-
50
- 运行测试:
51
- ```bash
52
- make test
53
- ```
File without changes