ErisPulse 2.1.0__tar.gz → 2.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- erispulse-2.1.1/.github/tools/merge_md.py +141 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/.github/tools/update-api-docs.py +100 -28
- {erispulse-2.1.0 → erispulse-2.1.1}/PKG-INFO +1 -1
- erispulse-2.1.1/docs/AI-Module-Generation.md +43 -0
- erispulse-2.1.1/docs/AIDocs/ErisPulse-AdapterDev.md +2448 -0
- erispulse-2.1.1/docs/AIDocs/ErisPulse-Core.md +1933 -0
- erispulse-2.1.0/docs/ForAIDocs/ErisPulseDevelop.md → erispulse-2.1.1/docs/AIDocs/ErisPulse-Full.md +1623 -909
- erispulse-2.1.1/docs/AIDocs/ErisPulse-ModuleDev.md +2496 -0
- erispulse-2.1.1/docs/AdapterStandards/APIResponse.md +109 -0
- erispulse-2.1.0/docs/Conversion-Standard/342/200/213.md → erispulse-2.1.1/docs/AdapterStandards/EventConversion.md +8 -0
- erispulse-2.1.1/docs/AdapterStandards/README.md +3 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/CHANGELOG.md +8 -0
- erispulse-2.1.0/docs/DEVELOPMENT.md → erispulse-2.1.1/docs/Development/Adapter.md +6 -111
- erispulse-2.1.1/docs/Development/Module.md +128 -0
- erispulse-2.1.1/docs/Development/README.md +3 -0
- erispulse-2.1.0/docs/ADAPTERS.md → erispulse-2.1.1/docs/PlatformFeatures.md +63 -67
- erispulse-2.1.1/docs/UseCore.md +138 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/api/ErisPulse/Core/adapter.md +71 -66
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/api/ErisPulse/Core/env.md +54 -6
- erispulse-2.1.1/docs/api/ErisPulse/Core/logger.md +85 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/api/ErisPulse/Core/mods.md +37 -5
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/api/ErisPulse/Core/raiserr.md +47 -6
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/api/ErisPulse/Core/server.md +48 -14
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/api/ErisPulse/Core/util.md +22 -5
- erispulse-2.1.1/docs/api/ErisPulse/__init__.md +318 -0
- erispulse-2.1.1/docs/api/ErisPulse/__main__.md +192 -0
- erispulse-2.1.1/docs/api/README.md +3 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/quick-start.md +3 -4
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-module/MyModule/Core.py +2 -2
- {erispulse-2.1.0 → erispulse-2.1.1}/pyproject.toml +1 -1
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/adapter.py +4 -75
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/logger.py +55 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/__init__.py +132 -113
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/__main__.py +115 -43
- erispulse-2.1.0/.github/tools/merge_md.py +0 -76
- erispulse-2.1.0/devs/search_pypi.py +0 -15
- erispulse-2.1.0/docs/AI-Module-Generation.md +0 -125
- erispulse-2.1.0/docs/UseCore.md +0 -224
- erispulse-2.1.0/docs/api/ErisPulse/__init__.md +0 -192
- erispulse-2.1.0/docs/api/ErisPulse/__main__.md +0 -34
- erispulse-2.1.0/docs/move2pypi.md +0 -124
- {erispulse-2.1.0 → erispulse-2.1.1}/.github/assets/erispulse_logo.png +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/.github/workflows/auto-tag-release.yml +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/.github/workflows/pypi-publish.yml +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/.gitignore +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/.python-version +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/CODE_OF_CONDUCT.md +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/LICENSE +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/README.md +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/devs/test.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/devs/test_adapter.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/devs/test_files/test.docx +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/devs/test_files/test.jpg +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/devs/test_files/test.mp4 +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/docs/CLI.md +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-adapter/LICENSE +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-adapter/MyAdapter/Core.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-adapter/MyAdapter/__init__.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-adapter/README.md +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-adapter/pyproject.toml +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-module/LICENSE +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-module/MyModule/__init__.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-module/README.md +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/examples/example-module/pyproject.toml +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/scripts/install/install.ps1 +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/scripts/install/install.sh +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/__init__.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/env.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/mods.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/raiserr.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/server.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/shellprint.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/src/ErisPulse/Core/util.py +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/style_guide/DOCSTRING_SPEC.md +0 -0
- {erispulse-2.1.0 → erispulse-2.1.1}/style_guide/README.md +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
def merge_md_files(output_file, files_to_merge, title="文档合集"):
|
|
4
|
+
"""
|
|
5
|
+
合并多个Markdown文件
|
|
6
|
+
|
|
7
|
+
:param output_file: 输出文件路径
|
|
8
|
+
:param files_to_merge: 要合并的文件列表,包含文件路径和描述
|
|
9
|
+
:param title: 文档标题
|
|
10
|
+
"""
|
|
11
|
+
with open(output_file, 'w', encoding='utf-8') as outfile:
|
|
12
|
+
# 写入头部说明
|
|
13
|
+
outfile.write(f"# ErisPulse {title}\n\n")
|
|
14
|
+
outfile.write("本文件由多个开发文档合并而成,用于辅助 AI 理解 ErisPulse 的相关功能。\n\n")
|
|
15
|
+
|
|
16
|
+
outfile.write("## 各文件对应内容说明\n\n")
|
|
17
|
+
outfile.write("| 文件名 | 作用 |\n")
|
|
18
|
+
outfile.write("|--------|------|\n")
|
|
19
|
+
|
|
20
|
+
# 写入文件说明
|
|
21
|
+
for file_info in files_to_merge:
|
|
22
|
+
outfile.write(f"| {os.path.basename(file_info['path'])} | {file_info.get('description', '')} |\n")
|
|
23
|
+
|
|
24
|
+
outfile.write("\n## 合并内容开始\n\n")
|
|
25
|
+
|
|
26
|
+
# 合并文件内容
|
|
27
|
+
for file_info in files_to_merge:
|
|
28
|
+
file_path = file_info['path']
|
|
29
|
+
if os.path.exists(file_path):
|
|
30
|
+
filename = os.path.basename(file_path)
|
|
31
|
+
with open(file_path, 'r', encoding='utf-8') as infile:
|
|
32
|
+
content = infile.read()
|
|
33
|
+
outfile.write(f"<!-- {filename} -->\n\n")
|
|
34
|
+
outfile.write(content)
|
|
35
|
+
outfile.write(f"\n\n<!--- End of {filename} -->\n\n")
|
|
36
|
+
else:
|
|
37
|
+
print(f"⚠️ 文件不存在,跳过: {file_path}")
|
|
38
|
+
|
|
39
|
+
def merge_api_docs(api_dir, output_file):
|
|
40
|
+
"""
|
|
41
|
+
合并API文档
|
|
42
|
+
|
|
43
|
+
:param api_dir: API文档目录
|
|
44
|
+
:param output_file: 输出文件路径
|
|
45
|
+
"""
|
|
46
|
+
with open(output_file, 'a', encoding='utf-8') as outfile:
|
|
47
|
+
outfile.write("<!-- API文档 -->\n\n")
|
|
48
|
+
outfile.write("# API参考\n\n")
|
|
49
|
+
|
|
50
|
+
# 递归遍历API目录
|
|
51
|
+
for root, _, files in os.walk(api_dir):
|
|
52
|
+
for file in files:
|
|
53
|
+
if file.endswith('.md'):
|
|
54
|
+
file_path = os.path.join(root, file)
|
|
55
|
+
rel_path = os.path.relpath(file_path, api_dir)
|
|
56
|
+
|
|
57
|
+
with open(file_path, 'r', encoding='utf-8') as infile:
|
|
58
|
+
content = infile.read()
|
|
59
|
+
outfile.write(f"## {rel_path}\n\n")
|
|
60
|
+
outfile.write(content)
|
|
61
|
+
outfile.write("\n\n")
|
|
62
|
+
|
|
63
|
+
outfile.write("<!--- End of API文档 -->\n")
|
|
64
|
+
|
|
65
|
+
def generate_full_document():
|
|
66
|
+
"""生成完整文档"""
|
|
67
|
+
print("⏳ 正在生成完整文档...")
|
|
68
|
+
|
|
69
|
+
# 定义要合并的文件
|
|
70
|
+
files_to_merge = [
|
|
71
|
+
{"path": "docs/quick-start.md", "description": "快速开始指南"},
|
|
72
|
+
{"path": "docs/UseCore.md", "description": "核心功能使用说明"},
|
|
73
|
+
{"path": "docs/PlatformFeatures.md", "description": "平台功能说明"},
|
|
74
|
+
{"path": "docs/Development/Module.md", "description": "模块开发指南"},
|
|
75
|
+
{"path": "docs/Development/Adapter.md", "description": "适配器开发指南"},
|
|
76
|
+
{"path": "docs/AdapterStandards/APIResponse.md", "description": "API响应标准"},
|
|
77
|
+
{"path": "docs/AdapterStandards/EventConversion.md", "description": "事件转换标准"},
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
output_file = "docs/AIDocs/ErisPulse-Full.md"
|
|
81
|
+
os.makedirs(os.path.dirname(output_file), exist_ok=True)
|
|
82
|
+
|
|
83
|
+
merge_md_files(output_file, files_to_merge, "完整开发文档")
|
|
84
|
+
merge_api_docs("docs/api", output_file)
|
|
85
|
+
|
|
86
|
+
print(f"🎉 完整文档生成完成,已保存到: {output_file}")
|
|
87
|
+
|
|
88
|
+
def generate_core_document():
|
|
89
|
+
"""生成核心功能文档"""
|
|
90
|
+
print("⏳ 正在生成核心功能文档...")
|
|
91
|
+
|
|
92
|
+
files_to_merge = [
|
|
93
|
+
{"path": "docs/quick-start.md", "description": "快速开始指南"},
|
|
94
|
+
{"path": "docs/UseCore.md", "description": "核心功能使用说明"},
|
|
95
|
+
{"path": "docs/PlatformFeatures.md", "description": "平台功能说明"},
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
output_file = "docs/AIDocs/ErisPulse-Core.md"
|
|
99
|
+
os.makedirs(os.path.dirname(output_file), exist_ok=True)
|
|
100
|
+
|
|
101
|
+
merge_md_files(output_file, files_to_merge, "核心功能文档")
|
|
102
|
+
merge_api_docs("docs/api/ErisPulse/Core", output_file)
|
|
103
|
+
|
|
104
|
+
print(f"🎉 核心功能文档生成完成,已保存到: {output_file}")
|
|
105
|
+
|
|
106
|
+
def generate_dev_documents():
|
|
107
|
+
"""生成开发文档(模块和适配器)"""
|
|
108
|
+
print("⏳ 正在生成开发文档...")
|
|
109
|
+
|
|
110
|
+
# 模块开发文档
|
|
111
|
+
module_files = [
|
|
112
|
+
{"path": "docs/UseCore.md", "description": "核心功能使用说明"},
|
|
113
|
+
{"path": "docs/PlatformFeatures.md", "description": "平台支持的发送类型及差异性说明"},
|
|
114
|
+
{"path": "docs/Development/Module.md", "description": "模块开发指南"}
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
module_output = "docs/AIDocs/ErisPulse-ModuleDev.md"
|
|
118
|
+
merge_md_files(module_output, module_files, "模块开发文档")
|
|
119
|
+
merge_api_docs("docs/api/", module_output)
|
|
120
|
+
print(f"🎉 模块开发文档生成完成,已保存到: {module_output}")
|
|
121
|
+
|
|
122
|
+
# 适配器开发文档
|
|
123
|
+
adapter_files = [
|
|
124
|
+
{"path": "docs/UseCore.md", "description": "核心功能使用说明"},
|
|
125
|
+
{"path": "docs/Development/Adapter.md", "description": "适配器开发指南"},
|
|
126
|
+
{"path": "docs/AdapterStandards/APIResponse.md", "description": "API响应标准"},
|
|
127
|
+
{"path": "docs/AdapterStandards/EventConversion.md", "description": "事件转换标准"},
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
adapter_output = "docs/AIDocs/ErisPulse-AdapterDev.md"
|
|
131
|
+
merge_md_files(adapter_output, adapter_files, "适配器开发文档")
|
|
132
|
+
merge_api_docs("docs/api", adapter_output)
|
|
133
|
+
print(f"🎉 适配器开发文档生成完成,已保存到: {adapter_output}")
|
|
134
|
+
|
|
135
|
+
if __name__ == "__main__":
|
|
136
|
+
# 生成所有文档
|
|
137
|
+
generate_full_document()
|
|
138
|
+
generate_core_document()
|
|
139
|
+
generate_dev_documents()
|
|
140
|
+
|
|
141
|
+
print("✅ 所有文档生成完成")
|
|
@@ -3,6 +3,7 @@ import ast
|
|
|
3
3
|
import re
|
|
4
4
|
import argparse
|
|
5
5
|
from typing import List, Dict, Tuple, Optional, Set
|
|
6
|
+
from datetime import datetime
|
|
6
7
|
|
|
7
8
|
def process_docstring(docstring: str) -> Optional[str]:
|
|
8
9
|
"""
|
|
@@ -15,30 +16,69 @@ def process_docstring(docstring: str) -> Optional[str]:
|
|
|
15
16
|
return None
|
|
16
17
|
|
|
17
18
|
# 检查忽略标签
|
|
18
|
-
if "{!--<
|
|
19
|
+
if "{!--< ignore >!--}" in docstring:
|
|
19
20
|
return None
|
|
20
21
|
|
|
22
|
+
# 替换 {!--< internal-use >!--}
|
|
23
|
+
docstring = re.sub(
|
|
24
|
+
r"{!--< internal-use >!--}(.*)",
|
|
25
|
+
lambda m: f"⚠️ **内部方法**:{m.group(1).strip()}\n\n",
|
|
26
|
+
docstring
|
|
27
|
+
)
|
|
28
|
+
|
|
21
29
|
# 替换过时标签
|
|
22
|
-
docstring =
|
|
30
|
+
docstring = re.sub(
|
|
31
|
+
r"\{!--< deprecated >!--\}(.*)",
|
|
32
|
+
lambda m: f"⚠️ **已弃用**:{m.group(1).strip()}\n\n",
|
|
33
|
+
docstring
|
|
34
|
+
)
|
|
23
35
|
|
|
24
36
|
# 替换实验性标签
|
|
25
|
-
docstring =
|
|
37
|
+
docstring = re.sub(
|
|
38
|
+
r"\{!--< experimental >!--\}(.*)",
|
|
39
|
+
lambda m: f"🔬 **实验性功能**:{m.group(1).strip()}\n\n",
|
|
40
|
+
docstring
|
|
41
|
+
)
|
|
26
42
|
|
|
27
|
-
#
|
|
43
|
+
# 处理提示标签(多行)
|
|
28
44
|
docstring = re.sub(
|
|
29
45
|
r"\{!--< tips >!--\}(.*?)\{!--< /tips >!--\}",
|
|
30
|
-
lambda m: f"
|
|
46
|
+
lambda m: f"💡 **提示**:\n\n{m.group(1).strip()}\n\n",
|
|
31
47
|
docstring,
|
|
32
48
|
flags=re.DOTALL
|
|
33
49
|
)
|
|
34
50
|
|
|
35
|
-
#
|
|
51
|
+
# 处理单行提示标签
|
|
36
52
|
docstring = re.sub(
|
|
37
53
|
r"\{!--< tips >!--\}([^\n]*)",
|
|
38
|
-
lambda m: f"
|
|
54
|
+
lambda m: f"💡 **提示**:{m.group(1).strip()}\n\n",
|
|
55
|
+
docstring
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# 参数说明
|
|
59
|
+
docstring = re.sub(
|
|
60
|
+
r":param (\w+):\s*\[([^\]]+)\]\s*(.*)",
|
|
61
|
+
lambda m: f"- `{m.group(1)}` ({m.group(2)}): {m.group(3).strip()}",
|
|
39
62
|
docstring
|
|
40
63
|
)
|
|
41
64
|
|
|
65
|
+
# 返回值说明
|
|
66
|
+
docstring = re.sub(
|
|
67
|
+
r":return:\s*\[([^\]]+)\]\s*(.*)",
|
|
68
|
+
lambda m: f"**返回**: \n\n- 类型: `{m.group(1)}`\n- 描述: {m.group(2).strip()}",
|
|
69
|
+
docstring
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# 异常说明
|
|
73
|
+
docstring = re.sub(
|
|
74
|
+
r":raises (\w+):\s*(.*)",
|
|
75
|
+
lambda m: f"⚠️ **可能抛出**: `{m.group(1)}` - {m.group(2).strip()}",
|
|
76
|
+
docstring
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# 统一换行符为两个换行
|
|
80
|
+
docstring = re.sub(r"\n{2,}", "\n\n", docstring.strip())
|
|
81
|
+
|
|
42
82
|
return docstring.strip()
|
|
43
83
|
|
|
44
84
|
def parse_python_file(file_path: str) -> Tuple[Optional[str], List[Dict], List[Dict]]:
|
|
@@ -84,7 +124,8 @@ def parse_python_file(file_path: str) -> Tuple[Optional[str], List[Dict], List[D
|
|
|
84
124
|
if processed_method_doc:
|
|
85
125
|
methods.append({
|
|
86
126
|
"name": item.name,
|
|
87
|
-
"doc": processed_method_doc
|
|
127
|
+
"doc": processed_method_doc,
|
|
128
|
+
"is_async": isinstance(item, ast.AsyncFunctionDef)
|
|
88
129
|
})
|
|
89
130
|
|
|
90
131
|
classes.append({
|
|
@@ -101,7 +142,8 @@ def parse_python_file(file_path: str) -> Tuple[Optional[str], List[Dict], List[D
|
|
|
101
142
|
if processed_func_doc:
|
|
102
143
|
functions.append({
|
|
103
144
|
"name": node.name,
|
|
104
|
-
"doc": processed_func_doc
|
|
145
|
+
"doc": processed_func_doc,
|
|
146
|
+
"is_async": isinstance(node, ast.AsyncFunctionDef)
|
|
105
147
|
})
|
|
106
148
|
|
|
107
149
|
return processed_module_doc, classes, functions
|
|
@@ -109,7 +151,7 @@ def parse_python_file(file_path: str) -> Tuple[Optional[str], List[Dict], List[D
|
|
|
109
151
|
def generate_markdown(module_path: str, module_doc: Optional[str],
|
|
110
152
|
classes: List[Dict], functions: List[Dict]) -> str:
|
|
111
153
|
"""
|
|
112
|
-
生成Markdown
|
|
154
|
+
生成Markdown格式API文档
|
|
113
155
|
|
|
114
156
|
:param module_path: 模块路径(点分隔)
|
|
115
157
|
:param module_doc: 模块文档
|
|
@@ -119,33 +161,54 @@ def generate_markdown(module_path: str, module_doc: Optional[str],
|
|
|
119
161
|
"""
|
|
120
162
|
content = []
|
|
121
163
|
|
|
122
|
-
#
|
|
123
|
-
content.append(f"# `{module_path}`
|
|
164
|
+
# 文档头部
|
|
165
|
+
content.append(f"""# 📦 `{module_path}` 模块
|
|
166
|
+
|
|
167
|
+
*自动生成于 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
""")
|
|
124
171
|
|
|
125
172
|
# 模块文档
|
|
126
173
|
if module_doc:
|
|
127
|
-
content.append(f"{module_doc}\n")
|
|
174
|
+
content.append(f"## 模块概述\n\n{module_doc}\n\n---\n")
|
|
128
175
|
|
|
129
176
|
# 函数部分
|
|
130
177
|
if functions:
|
|
131
|
-
content.append("## 函数\n")
|
|
178
|
+
content.append("## 🛠️ 函数\n")
|
|
132
179
|
for func in functions:
|
|
133
|
-
|
|
134
|
-
content.append(f"{func['
|
|
180
|
+
async_marker = "🔹 `async` " if func["is_async"] else ""
|
|
181
|
+
content.append(f"""### {async_marker}`{func['name']}`
|
|
182
|
+
|
|
183
|
+
{func['doc']}
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
""")
|
|
135
187
|
|
|
136
188
|
# 类部分
|
|
137
189
|
if classes:
|
|
138
|
-
content.append("## 类\n")
|
|
190
|
+
content.append("## 🏛️ 类\n")
|
|
139
191
|
for cls in classes:
|
|
140
|
-
content.append(f"### `{cls['name']}
|
|
141
|
-
|
|
192
|
+
content.append(f"""### `{cls['name']}`
|
|
193
|
+
|
|
194
|
+
{cls['doc']}
|
|
195
|
+
|
|
196
|
+
""")
|
|
142
197
|
|
|
143
198
|
# 类方法
|
|
144
199
|
if cls["methods"]:
|
|
145
|
-
content.append("#### 方法\n")
|
|
200
|
+
content.append("#### 🧰 方法\n")
|
|
146
201
|
for method in cls["methods"]:
|
|
147
|
-
|
|
148
|
-
content.append(f"{method['
|
|
202
|
+
async_marker = "🔹 `async` " if method["is_async"] else ""
|
|
203
|
+
content.append(f"""##### {async_marker}`{method['name']}`
|
|
204
|
+
|
|
205
|
+
{method['doc']}
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
""")
|
|
209
|
+
|
|
210
|
+
# 文档尾部
|
|
211
|
+
content.append(f"\n*文档最后更新于 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*")
|
|
149
212
|
|
|
150
213
|
return "\n".join(content)
|
|
151
214
|
|
|
@@ -167,20 +230,21 @@ def generate_api_docs(src_dir: str, output_dir: str):
|
|
|
167
230
|
|
|
168
231
|
# 计算模块路径
|
|
169
232
|
rel_path = os.path.relpath(file_path, src_dir)
|
|
170
|
-
module_path = rel_path.replace(".py", "").replace(os.sep, "
|
|
233
|
+
module_path = rel_path.replace(".py", "").replace(os.sep, ".")
|
|
171
234
|
|
|
172
235
|
# 解析Python文件
|
|
173
236
|
module_doc, classes, functions = parse_python_file(file_path)
|
|
174
237
|
|
|
175
238
|
# 跳过没有文档的文件
|
|
176
239
|
if not module_doc and not classes and not functions:
|
|
240
|
+
print(f"⏭️ 跳过无文档文件: {file_path}")
|
|
177
241
|
continue
|
|
178
242
|
|
|
179
243
|
# 生成Markdown内容
|
|
180
244
|
md_content = generate_markdown(module_path, module_doc, classes, functions)
|
|
181
245
|
|
|
182
246
|
# 写入文件
|
|
183
|
-
output_path = os.path.join(output_dir, f"{module_path}.md")
|
|
247
|
+
output_path = os.path.join(output_dir, f"{module_path.replace('.', '/')}.md")
|
|
184
248
|
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
|
185
249
|
|
|
186
250
|
with open(output_path, "w", encoding="utf-8") as f:
|
|
@@ -192,13 +256,21 @@ if __name__ == "__main__":
|
|
|
192
256
|
parser = argparse.ArgumentParser(description="API文档生成器")
|
|
193
257
|
parser.add_argument("--src", default="src", help="源代码目录 (默认: src)")
|
|
194
258
|
parser.add_argument("--output", default="docs/api", help="输出目录 (默认: docs/api)")
|
|
259
|
+
parser.add_argument("--version", action="version", version="API文档生成器 2.0")
|
|
195
260
|
|
|
196
261
|
args = parser.parse_args()
|
|
197
262
|
|
|
198
|
-
print(f"📁 源代码目录: {args.src}
|
|
199
|
-
|
|
200
|
-
|
|
263
|
+
print(f"""📁 源代码目录: {args.src}
|
|
264
|
+
📂 输出目录: {args.output}
|
|
265
|
+
⏳ 正在生成API文档...""")
|
|
201
266
|
|
|
202
267
|
generate_api_docs(args.src, args.output)
|
|
203
268
|
|
|
204
|
-
print("🎉 API文档生成完成!
|
|
269
|
+
print("""🎉 API文档生成完成!
|
|
270
|
+
|
|
271
|
+
生成文档包含以下改进:
|
|
272
|
+
✨ 更美观的排版和格式
|
|
273
|
+
📅 自动添加生成时间戳
|
|
274
|
+
🔖 使用emoji图标提高可读性
|
|
275
|
+
📝 优化了参数和返回值的显示方式
|
|
276
|
+
""")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# AI 模块生成指南
|
|
2
|
+
|
|
3
|
+
使用本指南,你可以通过AI快速生成符合ErisPulse规范的模块代码,无需从零开始编写。
|
|
4
|
+
|
|
5
|
+
## 快速开始
|
|
6
|
+
|
|
7
|
+
1. **获取开发文档**
|
|
8
|
+
下载 `docs/ForAIDocs/ErisPulseDevelop.md` - 它包含了所有AI需要的开发规范、适配器接口和SDK参考。
|
|
9
|
+
|
|
10
|
+
2. **明确你的需求**
|
|
11
|
+
确定模块功能、使用的适配器、依赖关系等核心要素。
|
|
12
|
+
|
|
13
|
+
3. **向AI描述需求**
|
|
14
|
+
使用下面的标准格式清晰地描述你的模块需求。
|
|
15
|
+
|
|
16
|
+
## 需求描述规范
|
|
17
|
+
|
|
18
|
+
请按照以下格式描述你的模块需求:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
我需要一个天气查询模块 WeatherBot,当用户在群聊中发送“/weather 上海”时,机器人会调用 OpenWeatherMap API 查询天气,并返回中文格式的天气信息。
|
|
22
|
+
|
|
23
|
+
请根据 ErisPulse 的模块规范和文档,为我生成完整的模块文件结构和代码
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
并且将刚刚下载的 `ErisPulseDevelop.md` 作为附件发送给 AI。
|
|
27
|
+
|
|
28
|
+
## 常见问题
|
|
29
|
+
|
|
30
|
+
Q: 推荐如何生成模块?
|
|
31
|
+
A: 使用你的 `IDE` 寻找一个AICoder,确保这个AICoder可以直接操作文件(当然,这只是推荐做法,你也可以直接按照AI给出的结构手动创建项目)。并且确保您的模型有足够的能力。
|
|
32
|
+
|
|
33
|
+
Q: 如何测试生成的模块?
|
|
34
|
+
A: 使用 pypi 包的形式安装到python环境,确保AI为你生成了包括 `pyproject.toml` 在内的python包配置文件和相应的代码。然后使用 `pip install -e .` 安装到python环境。
|
|
35
|
+
|
|
36
|
+
Q: 生成的代码不符合我的需求怎么办?
|
|
37
|
+
A: 可以调整需求描述后重新生成,或直接在生成代码基础上进行修改。
|
|
38
|
+
|
|
39
|
+
Q: 需要更复杂的功能怎么办?
|
|
40
|
+
A: 可以将复杂功能拆分为多个简单模块,或分阶段实现。
|
|
41
|
+
|
|
42
|
+
Q: 我可以把这个模块发布到ErisPulse吗?
|
|
43
|
+
A: 当然可以!但是我们会审查你的代码,确保它符合我们的规范。
|