Spaces:
Sleeping
Sleeping
| import ast | |
| import os | |
| def get_docstring(node): | |
| return ast.get_docstring(node) or "No description." | |
| def format_args(args): | |
| arg_names = [a.arg for a in args.args] | |
| if args.vararg: | |
| arg_names.append("*" + args.vararg.arg) | |
| if args.kwarg: | |
| arg_names.append("**" + args.kwarg.arg) | |
| return ", ".join(arg_names) | |
| def parse_file(filename): | |
| try: | |
| with open(filename, "r") as f: | |
| tree = ast.parse(f.read()) | |
| except Exception as e: | |
| return f"## {filename}\nError parsing file: {e}\n" | |
| docs = [] | |
| docs.append(f"## {filename}") | |
| file_doc = get_docstring(tree) | |
| if file_doc: | |
| docs.append(file_doc) | |
| docs.append("") | |
| for node in tree.body: | |
| if isinstance(node, ast.FunctionDef): | |
| sig = f"### `def {node.name}({format_args(node.args)})`" | |
| docs.append(sig) | |
| docs.append(get_docstring(node)) | |
| docs.append("") | |
| elif isinstance(node, ast.ClassDef): | |
| docs.append(f"### `class {node.name}`") | |
| docs.append(get_docstring(node)) | |
| docs.append("") | |
| for subnode in node.body: | |
| if isinstance(subnode, ast.FunctionDef): | |
| sig = f"#### `def {node.name}.{subnode.name}({format_args(subnode.args)})`" | |
| docs.append(sig) | |
| docs.append(get_docstring(subnode)) | |
| docs.append("") | |
| return "\n".join(docs) | |
| # Discover files | |
| discovery_dirs = ['.', 'research'] | |
| all_files = [] | |
| for d in discovery_dirs: | |
| if os.path.isdir(d): | |
| files_in_dir = sorted(os.listdir(d)) | |
| for f in files_in_dir: | |
| if f.endswith('.py') and not f.startswith('__'): | |
| path = os.path.join(d, f) if d != '.' else f | |
| if os.path.isfile(path): | |
| all_files.append(path) | |
| full_docs = ["# API Documentation\n"] | |
| for f in all_files: | |
| full_docs.append(parse_file(f)) | |
| with open("docs/API.md", "w") as f: | |
| f.write("\n".join(full_docs)) | |
| print(f"Generated documentation for {len(all_files)} files.") | |