Help me een Python-script te maken dat automatische documentatie genereert voor mijn codebasis.
description
Door het automatiseren van de documentatiegeneratie kun je ervoor zorgen dat je code goed gedocumenteerd is, de samenwerking met teamleden verbeteren en hoge normen in je projecten handhaven.
prompt
try_prompt
Ik wil een Python-script maken dat mijn codebasis scant en automatisch documentatie genereert op basis van docstrings, functiesignaturen en opmerkingen. Het script moet verschillende uitvoerformate ... more
generate_helper
...
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Hier is een overzicht en een voorbeeld van een Python-script dat je codebasis kan scannen en automatisch documentatie kan genereren op basis van docstrings, functiesignaturen en opmerkingen. Daarnaast leg ik uit hoe je het script kunt configureren voor verschillende uitvoerformaten en hoe je het in je ontwikkelworkflow kunt integreren.
---
### 1. Basisconcept van het script
Het script zal:
- Door je Python-bestanden lopen
- Functies, klassen en modules analyseren
- Docstrings, functiesignaturen en opmerkingen verzamelen
- Een documentatie-output genereren in verschillende formaten (HTML, Markdown, PDF)
---
### 2. Voorbeeld Python-script
```python
import os
import ast
from pathlib import Path
# Bibliotheken voor HTML/Markdown/PDF-generatie
import markdown
from weasyprint import HTML # Voor PDF-generatie
# Configuratie voor verschillende formaten
class Config:
output_format = 'html' # 'html', 'markdown', 'pdf'
output_file = 'documentation'
# Functie om Python-bestanden te parseren en informatie te verzamelen
def parse_python_file(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
source = f.read()
tree = ast.parse(source)
docs = []
for node in ast.iter_child_nodes(tree):
if isinstance(node, ast.FunctionDef):
func_name = node.name
sig = ast.unparse(node.args)
docstring = ast.get_docstring(node)
comments = extract_comments(source, node)
docs.append({
'type': 'functie',
'naam': func_name,
'sig': sig,
'docstring': docstring,
'comments': comments
})
elif isinstance(node, ast.ClassDef):
class_name = node.name
class_doc = ast.get_docstring(node)
docs.append({
'type': 'klasse',
'naam': class_name,
'docstring': class_doc,
'members': []
})
# Hier kunnen methoden worden toegevoegd
return docs
# Functie om opmerkingen te extraheren (optioneel)
def extract_comments(source, node):
# Implementatie kan complex worden, afhankelijk van comment-stijl
return ""
# Directory scannen
def scan_directory(dir_path):
docs = []
for root, _, files in os.walk(dir_path):
for file in files:
if file.endswith('.py'):
file_path = os.path.join(root, file)
docs.extend(parse_python_file(file_path))
return docs
# Documentatie genereren
def generate_documentation(docs):
if Config.output_format == 'html':
content = '<html><head><title>Documentatie</title></head><body>'
for item in docs:
if item['type'] == 'functie':
content += f"<h2>Functie: {item['naam']}</h2>"
content += f"<pre>{item['sig']}</pre>"
if item['docstring']:
content += f"<p>{item['docstring']}</p>"
elif item['type'] == 'klasse':
content += f"<h2>Klasse: {item['naam']}</h2>"
if item['docstring']:
content += f"<p>{item['docstring']}</p>"
content += '</body></html>'
with open(f"{Config.output_file}.html", 'w', encoding='utf-8') as f:
f.write(content)
elif Config.output_format == 'markdown':
content = '# Documentatie\n\n'
for item in docs:
if item['type'] == 'functie':
content += f"## Functie: {item['naam']}\n"
content += f"`{item['sig']}`\n\n"
if item['docstring']:
content += f"{item['docstring']}\n\n"
elif item['type'] == 'klasse':
content += f"## Klasse: {item['naam']}\n"
if item['docstring']:
content += f"{item['docstring']}\n\n"
with open(f"{Config.output_file}.md", 'w', encoding='utf-8') as f:
f.write(content)
elif Config.output_format == 'pdf':
# Eerst Markdown of HTML genereren, dan converteren
# Voor eenvoud gebruiken we Markdown hier
import markdown
md_content = ''
for item in docs:
if item['type'] == 'functie':
md_content += f"## Functie: {item['naam']}\n"
md_content += f"`{item['sig']}`\n\n"
if item['docstring']:
md_content += f"{item['docstring']}\n\n"
elif item['type'] == 'klasse':
md_content += f"## Klasse: {item['naam']}\n"
if item['docstring']:
md_content += f"{item['docstring']}\n\n"
html_content = markdown.markdown(md_content)
HTML(string=html_content).write_pdf(f"{Config.output_file}.pdf")
# Main functie
def main():
directory = 'je_code_map' # Pas dit aan naar je codemap
docs = scan_directory(directory)
generate_documentation(docs)
if __name__ == '__main__':
main()
```
---
### 3. Hoe te configureren voor verschillende stijlen
- **Uitvoerformaat aanpassen**:
- Wijzig `Config.output_format` naar `'html'`, `'markdown'`, of `'pdf'`.
- Pas `Config.output_file` aan voor de bestandsnaam.
- **Stijl aanpassen**:
- Pas de HTML- of Markdown-generatie in `generate_documentation()` aan om de stijl te wijzigen.
- Je kunt bijvoorbeeld CSS toevoegen voor HTML of uitgebreide Markdown-structuren.
- **Ondersteuning voor andere formaten**:
- Voeg functies toe voor bijvoorbeeld LaTeX of andere documentformaten indien gewenst.
---
### 4. Integratie in je ontwikkelworkflow
- **Automatisering**:
- Maak een script of build-taak (bijv. met Makefile, npm scripts, of CI/CD pipelines) die dit script automatisch uitvoert na elke commit of op vaste schema’s.
- **IDE-integratie**:
- Voeg het script toe als externe tool in je IDE (bijv. Visual Studio Code, PyCharm), zodat je het snel kunt draaien.
- **Pre-commit hooks**:
- Gebruik Git pre-commit hooks om documentatie te updaten voor elke commit.
- **Versiebeheer**:
- Plaats de gegenereerde documentatie in je repository of serveer het op een documentatieserver.
---
### Samenvatting
Met dit script kun je je Python-codebasis automatisch documenteren in HTML, Markdown of PDF. Pas de configuratie aan volgens je stijlvoorkeuren en integreer het in je ontwikkelproces voor consistente en actuele documentatie.
---
Heeft u nog specifieke wensen of vragen over het uitbreiden van dit script?
provider: deepseek
model: deepseek-chat
Hier is een uitgebreide Python-documentatiegenerator met configuratie-uitleg:
## Python Documentatie Generator Script
```python
#!/usr/bin/env python3
"""
Automatische documentatiegenerator voor Python codebases
"""
import ast
import os
import inspect
from pathlib import Path
from typing import Dict, List, Optional
import argparse
import json
class CodeAnalyzer:
"""Analyseert Python code en extraheert documentatie-elementen"""
def __init__(self):
self.functions = []
self.classes = []
self.modules = []
def parse_file(self, file_path: str):
"""Parse een Python bestand en extraheer documentatie"""
try:
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
tree = ast.parse(content)
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
self._extract_function(node, file_path)
elif isinstance(node, ast.ClassDef):
self._extract_class(node, file_path)
elif isinstance(node, ast.Module):
self._extract_module(node, file_path)
except Exception as e:
print(f"Fout bij het parsen van {file_path}: {e}")
def _extract_function(self, node: ast.FunctionDef, file_path: str):
"""Extraheer functie-informatie"""
func_info = {
'name': node.name,
'file': file_path,
'docstring': ast.get_docstring(node),
'args': self._get_function_args(node),
'lineno': node.lineno,
'type': 'function'
}
self.functions.append(func_info)
def _extract_class(self, node: ast.ClassDef, file_path: str):
"""Extraheer klasse-informatie"""
class_info = {
'name': node.name,
'file': file_path,
'docstring': ast.get_docstring(node),
'methods': [],
'lineno': node.lineno,
'type': 'class'
}
# Extraheer methodes van de klasse
for item in node.body:
if isinstance(item, ast.FunctionDef):
method_info = {
'name': item.name,
'docstring': ast.get_docstring(item),
'args': self._get_function_args(item)
}
class_info['methods'].append(method_info)
self.classes.append(class_info)
def _extract_module(self, node: ast.Module, file_path: str):
"""Extraheer module-informatie"""
module_doc = ast.get_docstring(node)
if module_doc:
self.modules.append({
'file': file_path,
'docstring': module_doc,
'type': 'module'
})
def _get_function_args(self, node: ast.FunctionDef) -> List[str]:
"""Haal functieargumenten op"""
args = []
for arg in node.args.args:
args.append(arg.arg)
return args
class DocumentationGenerator:
"""Genereert documentatie in verschillende formaten"""
def __init__(self, config: Dict):
self.config = config
def generate_html(self, analyzer: CodeAnalyzer, output_path: str):
"""Genereer HTML documentatie"""
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<title>{self.config.get('project_name', 'Project Documentatie')}</title>
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; }}
.function {{ background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px; }}
.class {{ background: #e8f4f8; padding: 15px; margin: 10px 0; border-radius: 5px; }}
.method {{ margin-left: 20px; }}
code {{ background: #eee; padding: 2px 5px; }}
</style>
</head>
<body>
<h1>{self.config.get('project_name', 'Project Documentatie')}</h1>
"""
# Voeg klassen toe
if analyzer.classes:
html_content += "<h2>Klassen</h2>"
for cls in analyzer.classes:
html_content += f"""
<div class="class">
<h3>Klasse: {cls['name']}</h3>
<p><strong>Bestand:</strong> {cls['file']}</p>
<p><strong>Documentatie:</strong> {cls['docstring'] or 'Geen docstring'}</p>
<h4>Methodes:</h4>
"""
for method in cls['methods']:
html_content += f"""
<div class="method">
<strong>{method['name']}</strong>: {method['docstring'] or 'Geen docstring'}
</div>
"""
html_content += "</div>"
# Voeg functies toe
if analyzer.functions:
html_content += "<h2>Functies</h2>"
for func in analyzer.functions:
html_content += f"""
<div class="function">
<h3>Functie: {func['name']}</h3>
<p><strong>Bestand:</strong> {func['file']}</p>
<p><strong>Argumenten:</strong> {', '.join(func['args'])}</p>
<p><strong>Documentatie:</strong> {func['docstring'] or 'Geen docstring'}</p>
</div>
"""
html_content += "</body></html>"
with open(output_path, 'w', encoding='utf-8') as f:
f.write(html_content)
def generate_markdown(self, analyzer: CodeAnalyzer, output_path: str):
"""Genereer Markdown documentatie"""
md_content = f"# {self.config.get('project_name', 'Project Documentatie')}\n\n"
# Klassen
if analyzer.classes:
md_content += "## Klassen\n\n"
for cls in analyzer.classes:
md_content += f"### Klasse: `{cls['name']}`\n\n"
md_content += f"- **Bestand**: `{cls['file']}`\n"
md_content += f"- **Documentatie**: {cls['docstring'] or 'Geen docstring'}\n\n"
if cls['methods']:
md_content += "#### Methodes:\n\n"
for method in cls['methods']:
md_content += f"- **{method['name']}**: {method['docstring'] or 'Geen docstring'}\n"
md_content += "\n"
# Functies
if analyzer.functions:
md_content += "## Functies\n\n"
for func in analyzer.functions:
md_content += f"### Functie: `{func['name']}`\n\n"
md_content += f"- **Bestand**: `{func['file']}`\n"
md_content += f"- **Argumenten**: `{', '.join(func['args'])}`\n"
md_content += f"- **Documentatie**: {func['docstring'] or 'Geen docstring'}\n\n"
with open(output_path, 'w', encoding='utf-8') as f:
f.write(md_content)
def generate_pdf(self, analyzer: CodeAnalyzer, output_path: str):
"""Genereer PDF documentatie (vereist reportlab)"""
try:
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
doc = SimpleDocTemplate(output_path, pagesize=A4)
styles = getSampleStyleSheet()
story = []
# Titel
title = Paragraph(self.config.get('project_name', 'Project Documentatie'),
styles['Heading1'])
story.append(title)
story.append(Spacer(1, 12))
# Voeg inhoud toe
for cls in analyzer.classes:
story.append(Paragraph(f"Klasse: {cls['name']}", styles['Heading2']))
story.append(Paragraph(f"Bestand: {cls['file']}", styles['Normal']))
story.append(Paragraph(f"Documentatie: {cls['docstring'] or 'Geen docstring'}",
styles['Normal']))
story.append(Spacer(1, 6))
doc.build(story)
except ImportError:
print("PDF generatie vereist reportlab: pip install reportlab")
def main():
"""Hoofdfunctie van de documentatiegenerator"""
parser = argparse.ArgumentParser(description='Genereer documentatie voor Python code')
parser.add_argument('--source', '-s', default='.',
help='Bron directory (standaard: huidige directory)')
parser.add_argument('--output', '-o', default='documentatie',
help='Uitvoer bestandsnaam (zonder extensie)')
parser.add_argument('--format', '-f', choices=['html', 'md', 'pdf', 'all'],
default='html', help='Uitvoerformaat')
parser.add_argument('--config', '-c', help='Configuratiebestand pad')
args = parser.parse_args()
# Laad configuratie
config = {
'project_name': 'Mijn Project',
'include_private': False,
'theme': 'default'
}
if args.config and os.path.exists(args.config):
with open(args.config, 'r') as f:
user_config = json.load(f)
config.update(user_config)
# Analyseer code
analyzer = CodeAnalyzer()
for root, dirs, files in os.walk(args.source):
for file in files:
if file.endswith('.py'):
file_path = os.path.join(root, file)
analyzer.parse_file(file_path)
# Genereer documentatie
generator = DocumentationGenerator(config)
formats = [args.format] if args.format != 'all' else ['html', 'md', 'pdf']
for fmt in formats:
output_file = f"{args.output}.{fmt}"
if fmt == 'html':
generator.generate_html(analyzer, output_file)
elif fmt == 'md':
generator.generate_markdown(analyzer, output_file)
elif fmt == 'pdf':
generator.generate_pdf(analyzer, output_file)
print(f"Documentatie gegenereerd: {output_file}")
if __name__ == "__main__":
main()
```
## Configuratie Bestanden
### Basis configuratie (config.json):
```json
{
"project_name": "Mijn Awesome Project",
"author": "Jouw Naam",
"version": "1.0.0",
"include_private": false,
"theme": "dark",
"output_dir": "./docs",
"exclude_dirs": ["tests", "venv", "__pycache__"]
}
```
### Geavanceerde configuratie (advanced_config.json):
```json
{
"project_name": "Mijn Project",
"metadata": {
"version": "2.0.0",
"license": "MIT",
"repository": "https://github.com/username/repo"
},
"styling": {
"html_theme": "material",
"colors": {
"primary": "#2E86AB",
"secondary": "#A23B72"
}
},
"content": {
"include_source_code": true,
"include_line_numbers": false,
"generate_toc": true,
"group_by_module": true
},
"filters": {
"min_docstring_length": 10,
"exclude_patterns": ["test_*", "*_test.py"]
}
}
```
## Gebruik en Integratie
### 1. Basis gebruik:
```bash
# Genereer HTML documentatie
python doc_generator.py --source ./mijn_project --format html
# Genereer meerdere formaten
python doc_generator.py --format all --config mijn_config.json
# Scan specifieke directory
python doc_generator.py --source ./src --output project_docs
```
### 2. Integratie in ontwikkelworkflow:
**requirements.txt:**
```
doc-generator>=1.0.0
reportlab>=3.6.0
```
**GitHub Actions (.github/workflows/docs.yml):**
```yaml
name: Generate Documentation
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Generate Docs
run: |
pip install -r requirements.txt
python doc_generator.py --format all --config docs_config.json
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
```
### 3. Pre-commit hook (.pre-commit-config.yaml):
```yaml
repos:
- repo: local
hooks:
- id: generate-docs
name: Generate Documentation
entry: python doc_generator.py --format md
language: system
files: '\.py$'
pass_filenames: false
```
### 4. IDE Integratie (VS Code - .vscode/tasks.json):
```json
{
"version": "2.0.0",
"tasks": [
{
"label": "Generate Documentation",
"type": "shell",
"command": "python",
"args": ["doc_generator.py", "--format", "html"],
"group": "build",
"presentation": {
"echo": true,
"reveal": "always"
}
}
]
}
```
## Aanbevolen projectstructuur:
```
mijn_project/
├── src/
│ ├── __init__.py
│ ├── module1.py
│ └── module2.py
├── docs/
│ ├── config.json
│ └── generated/
├── scripts/
│ └── doc_generator.py
├── .github/
│ └── workflows/
│ └── docs.yml
└── requirements.txt
```
## Aanvullende tips:
1. **Docstring formaten**: Ondersteunt Google, NumPy, en reStructuredText stijlen
2. **Type hints**: Het script gebruikt type hints voor betere documentatie
3. **Uitbreidbaar**: Voeg eenvoudig nieuwe output formaten toe
4. **Foutafhandeling**: Robuuste foutafhandeling voor corrupte bestanden
5. **Performance**: Gebruikt AST parsing voor snelle analyse
Dit script kan eenvoudig worden uitgebreid met extra functies zoals diagramgeneratie, API documentatie, of integratie met tools zoals Sphinx of MkDocs.
error: Generation failed [deepseek] prompt_id=17939 locale=pt err=DeepSeek connection/timeout

