drf-to-mkdoc 0.2.4__py3-none-any.whl → 0.3.1__py3-none-any.whl
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 drf-to-mkdoc might be problematic. Click here for more details.
- drf_to_mkdoc/conf/defaults.py +2 -2
- drf_to_mkdoc/conf/settings.py +3 -1
- drf_to_mkdoc/management/commands/build_model_docs.py +10 -1
- drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/request-executor.js +18 -2
- drf_to_mkdoc/templates/er_diagrams/app.html +26 -0
- drf_to_mkdoc/templates/er_diagrams/index.html +14 -0
- drf_to_mkdoc/templates/er_diagrams/main.html +22 -0
- drf_to_mkdoc/utils/endpoint_detail_generator.py +1 -1
- drf_to_mkdoc/utils/er_diagram_generator.py +230 -0
- drf_to_mkdoc/utils/schema.py +10 -1
- drf_to_mkdoc-0.3.1.dist-info/METADATA +232 -0
- {drf_to_mkdoc-0.2.4.dist-info → drf_to_mkdoc-0.3.1.dist-info}/RECORD +15 -11
- drf_to_mkdoc-0.2.4.dist-info/METADATA +0 -295
- {drf_to_mkdoc-0.2.4.dist-info → drf_to_mkdoc-0.3.1.dist-info}/WHEEL +0 -0
- {drf_to_mkdoc-0.2.4.dist-info → drf_to_mkdoc-0.3.1.dist-info}/licenses/LICENSE +0 -0
- {drf_to_mkdoc-0.2.4.dist-info → drf_to_mkdoc-0.3.1.dist-info}/top_level.txt +0 -0
drf_to_mkdoc/conf/defaults.py
CHANGED
|
@@ -2,6 +2,7 @@ DEFAULTS = {
|
|
|
2
2
|
# Path configurations with defaults
|
|
3
3
|
"DOCS_DIR": "docs", # Directory where docs will be generated
|
|
4
4
|
"CONFIG_DIR": "docs/configs", # Directory for configuration files
|
|
5
|
+
"ER_DIAGRAMS_DIR": "er_diagrams", # Directory for ER diagrams (relative to DOCS_DIR)
|
|
5
6
|
"MODEL_DOCS_FILE": "docs/model-docs.json", # Path to model documentation JSON file
|
|
6
7
|
"DOC_CONFIG_FILE": "docs/configs/doc_config.json", # Path to documentation configuration file
|
|
7
8
|
"CUSTOM_SCHEMA_FILE": "docs/configs/custom_schema.json", # Path to custom schema file
|
|
@@ -13,6 +14,5 @@ DEFAULTS = {
|
|
|
13
14
|
"AI_CONFIG_DIR_NAME": "ai_code", # Directory name for AI-generated code files
|
|
14
15
|
"AI_OPERATION_MAP_FILE": "docs/configs/operation_map.json", # Path to operation map file
|
|
15
16
|
"SERIALIZERS_INHERITANCE_DEPTH": 1, # Maximum depth for class inheritance analysis
|
|
16
|
-
#
|
|
17
|
-
"DJANGO_APPS": None, # List of Django app names to process
|
|
17
|
+
"DJANGO_APPS": [], # If it is empty list, there is no any exclusion
|
|
18
18
|
}
|
drf_to_mkdoc/conf/settings.py
CHANGED
|
@@ -7,13 +7,14 @@ from drf_to_mkdoc.conf.defaults import DEFAULTS
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class DRFToMkDocSettings:
|
|
10
|
-
required_settings: ClassVar[list[str]] = [
|
|
10
|
+
required_settings: ClassVar[list[str]] = []
|
|
11
11
|
project_settings: ClassVar[dict[str, Any]] = {"PROJECT_NAME": "drf-to-mkdoc"}
|
|
12
12
|
|
|
13
13
|
settings_types: ClassVar[dict[str, type]] = {
|
|
14
14
|
"ENABLE_AI_DOCS": bool,
|
|
15
15
|
"AI_CONFIG_DIR_NAME": str,
|
|
16
16
|
"SERIALIZERS_INHERITANCE_DEPTH": int,
|
|
17
|
+
"DJANGO_APPS": list,
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
settings_ranges: ClassVar[dict[str, tuple[int, int]]] = {
|
|
@@ -22,6 +23,7 @@ class DRFToMkDocSettings:
|
|
|
22
23
|
|
|
23
24
|
path_settings = {
|
|
24
25
|
"CONFIG_DIR",
|
|
26
|
+
"ER_DIAGRAMS_DIR",
|
|
25
27
|
"MODEL_DOCS_FILE",
|
|
26
28
|
"DOC_CONFIG_FILE",
|
|
27
29
|
"CUSTOM_SCHEMA_FILE",
|
|
@@ -4,6 +4,7 @@ from django.core.management.base import BaseCommand
|
|
|
4
4
|
|
|
5
5
|
from drf_to_mkdoc.conf.settings import drf_to_mkdoc_settings
|
|
6
6
|
from drf_to_mkdoc.utils.commons.file_utils import load_json_data
|
|
7
|
+
from drf_to_mkdoc.utils.er_diagram_generator import generate_er_diagrams
|
|
7
8
|
from drf_to_mkdoc.utils.model_detail_generator import generate_model_docs
|
|
8
9
|
from drf_to_mkdoc.utils.model_list_generator import create_models_index
|
|
9
10
|
|
|
@@ -42,9 +43,17 @@ class Command(BaseCommand):
|
|
|
42
43
|
self.stdout.write("📋 Generating model documentation...")
|
|
43
44
|
|
|
44
45
|
try:
|
|
46
|
+
# Generate model detail pages
|
|
45
47
|
generate_model_docs(models_data)
|
|
48
|
+
self.stdout.write(self.style.SUCCESS("✅ Model detail pages generated"))
|
|
49
|
+
|
|
50
|
+
# Generate ER diagrams
|
|
51
|
+
generate_er_diagrams(models_data, docs_dir)
|
|
52
|
+
self.stdout.write(self.style.SUCCESS("✅ ER diagrams generated"))
|
|
53
|
+
|
|
54
|
+
# Create models index page
|
|
46
55
|
create_models_index(models_data, docs_dir)
|
|
47
|
-
self.stdout.write(self.style.SUCCESS("✅
|
|
56
|
+
self.stdout.write(self.style.SUCCESS("✅ Models index page generated"))
|
|
48
57
|
except Exception as e:
|
|
49
58
|
self.stdout.write(self.style.WARNING(f"⚠️ Failed to generate model docs: {e}"))
|
|
50
59
|
raise
|
|
@@ -160,9 +160,25 @@ const RequestExecutor = {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
// Get method
|
|
163
|
+
// Get method - try multiple sources for reliability
|
|
164
|
+
let method = 'GET'; // Default fallback
|
|
165
|
+
|
|
166
|
+
// First try: method badge data attribute
|
|
164
167
|
const methodBadge = document.querySelector('.method-badge');
|
|
165
|
-
|
|
168
|
+
if (methodBadge?.dataset.method) {
|
|
169
|
+
method = methodBadge.dataset.method;
|
|
170
|
+
} else {
|
|
171
|
+
// Second try: try-out form data attribute
|
|
172
|
+
const tryOutForm = document.querySelector('.try-out-form');
|
|
173
|
+
if (tryOutForm?.dataset.method) {
|
|
174
|
+
method = tryOutForm.dataset.method.toUpperCase();
|
|
175
|
+
} else {
|
|
176
|
+
// Third try: method badge text content
|
|
177
|
+
if (methodBadge?.textContent) {
|
|
178
|
+
method = methodBadge.textContent.trim();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
166
182
|
|
|
167
183
|
return {
|
|
168
184
|
url: fullUrl,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# {{ app_name|title|cut:"_"|safe }} Models
|
|
2
|
+
|
|
3
|
+
```mermaid
|
|
4
|
+
erDiagram
|
|
5
|
+
{% for entity in app_entities %}
|
|
6
|
+
{{ entity.model_name }} {
|
|
7
|
+
{% for field in entity.fields %}
|
|
8
|
+
{{ field.name }} {{ field.type }}{% if field.is_pk %} "PK"{% elif field.nullable %} "NULLABLE"{% endif %}
|
|
9
|
+
{% endfor %}
|
|
10
|
+
}
|
|
11
|
+
{% endfor %}
|
|
12
|
+
{% for entity in related_entities %}
|
|
13
|
+
{{ entity.model_name }} {
|
|
14
|
+
id AutoField "PK"
|
|
15
|
+
}
|
|
16
|
+
{% endfor %}
|
|
17
|
+
{% for relationship in relationships %}
|
|
18
|
+
{{ relationship.source_model }} {{ relationship.type }} {{ relationship.target_model }} : "{{ relationship.description }}"
|
|
19
|
+
{% endfor %}
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Models
|
|
24
|
+
|
|
25
|
+
{% for entity in app_entities %}- [{{ entity.model_name }}](../../models/{{ entity.app_name }}/{{ entity.table_name }}/)
|
|
26
|
+
{% endfor %}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Entity-Relationship Diagrams
|
|
2
|
+
|
|
3
|
+
This section contains Entity-Relationship (ER) diagrams for all Django models in the system.
|
|
4
|
+
|
|
5
|
+
## [Complete System Diagram](main.md)
|
|
6
|
+
|
|
7
|
+
View the complete ER diagram showing all models and their relationships.
|
|
8
|
+
|
|
9
|
+
## Application Diagrams
|
|
10
|
+
|
|
11
|
+
| Application | Models
|
|
12
|
+
|------------|--------|
|
|
13
|
+
{% for app in apps %}| [{{ app.name|title|cut:"_"|safe }}]({{ app.name }}.md) | {{ app.model_count }} |
|
|
14
|
+
{% endfor %}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Complete Entity-Relationship Diagram
|
|
2
|
+
|
|
3
|
+
```mermaid
|
|
4
|
+
erDiagram
|
|
5
|
+
{% for entity in entities %}
|
|
6
|
+
{{ entity.model_name }} {
|
|
7
|
+
{% for field in entity.fields %}
|
|
8
|
+
{{ field.name }} {{ field.type }}{% if field.is_pk %} "PK"{% elif field.nullable %} "NULLABLE"{% endif %}
|
|
9
|
+
{% endfor %}
|
|
10
|
+
}
|
|
11
|
+
{% endfor %}
|
|
12
|
+
{% for relationship in relationships %}
|
|
13
|
+
{{ relationship.source_model }} {{ relationship.type }} {{ relationship.target_model }} : "{{ relationship.description }}"
|
|
14
|
+
{% endfor %}
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
<div class="er-diagram-controls">
|
|
19
|
+
<button class="zoom-in">Zoom In</button>
|
|
20
|
+
<button class="zoom-out">Zoom Out</button>
|
|
21
|
+
<button class="reset-zoom">Reset</button>
|
|
22
|
+
</div>
|
|
@@ -742,7 +742,7 @@ def parse_endpoints_from_schema(paths: dict[str, Any]) -> dict[str, list[dict[st
|
|
|
742
742
|
|
|
743
743
|
for path, methods in paths.items():
|
|
744
744
|
app_name = extract_app_from_operation_id(next(iter(methods.values()))["operationId"])
|
|
745
|
-
if app_name not in django_apps:
|
|
745
|
+
if django_apps and app_name not in django_apps:
|
|
746
746
|
continue
|
|
747
747
|
|
|
748
748
|
for method, endpoint_data in methods.items():
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from django.template.loader import render_to_string
|
|
5
|
+
|
|
6
|
+
from drf_to_mkdoc.conf.settings import drf_to_mkdoc_settings
|
|
7
|
+
|
|
8
|
+
from .commons.file_utils import write_file
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _get_relationship_type_and_description(rel_type_class: str) -> tuple[str, str] | None:
|
|
12
|
+
"""Map Django relationship type to Mermaid ER diagram syntax and description."""
|
|
13
|
+
mapping = {
|
|
14
|
+
"ForeignKey": ("}o--||", "many to 1"),
|
|
15
|
+
"OneToOneField": ("||--||", "1 to 1"),
|
|
16
|
+
"OneToOneRel": ("||--||", "1 to 1"),
|
|
17
|
+
"ManyToManyField": ("}o--o{", "many to many"),
|
|
18
|
+
"ManyToManyRel": ("}o--o{", "many to many"),
|
|
19
|
+
"ManyToOneRel": ("||--o{", "1 to many"),
|
|
20
|
+
}
|
|
21
|
+
return mapping.get(rel_type_class)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _create_entity_from_model(
|
|
25
|
+
app_name: str, model_name: str, model_info: dict[str, Any], include_fields: bool = False
|
|
26
|
+
) -> dict[str, Any]:
|
|
27
|
+
"""Create entity dictionary from model data, optionally including field details."""
|
|
28
|
+
table_name = model_info.get("table_name", model_name)
|
|
29
|
+
entity_id = f"{app_name}__{table_name}"
|
|
30
|
+
|
|
31
|
+
entity = {
|
|
32
|
+
"id": entity_id,
|
|
33
|
+
"app_name": app_name,
|
|
34
|
+
"model_name": model_name,
|
|
35
|
+
"table_name": table_name,
|
|
36
|
+
"fields": [],
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if include_fields:
|
|
40
|
+
fields = []
|
|
41
|
+
has_pk = False
|
|
42
|
+
|
|
43
|
+
for field_name, field_info in model_info.get("column_fields", {}).items():
|
|
44
|
+
field_type = field_info.get("type", "")
|
|
45
|
+
is_pk = field_info.get("primary_key", False)
|
|
46
|
+
nullable = field_info.get("null", False) or field_info.get("blank", False)
|
|
47
|
+
|
|
48
|
+
fields.append({
|
|
49
|
+
"name": field_name,
|
|
50
|
+
"type": field_type,
|
|
51
|
+
"is_pk": is_pk,
|
|
52
|
+
"nullable": nullable
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
if is_pk:
|
|
56
|
+
has_pk = True
|
|
57
|
+
|
|
58
|
+
if not has_pk:
|
|
59
|
+
fields.insert(0, {
|
|
60
|
+
"name": "id",
|
|
61
|
+
"type": "AutoField",
|
|
62
|
+
"is_pk": True,
|
|
63
|
+
"nullable": False
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
entity["fields"] = fields
|
|
67
|
+
|
|
68
|
+
return entity
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _process_model_relationships(
|
|
72
|
+
source_entity_id: str,
|
|
73
|
+
source_model_name: str,
|
|
74
|
+
model_info: dict[str, Any],
|
|
75
|
+
all_models_data: dict[str, Any]
|
|
76
|
+
) -> list[dict[str, Any]]:
|
|
77
|
+
"""Extract and process model relationships, returning Mermaid-compatible relationship data."""
|
|
78
|
+
relationships = []
|
|
79
|
+
|
|
80
|
+
for rel_name, rel_info in model_info.get("relationships", {}).items():
|
|
81
|
+
if not isinstance(rel_info, dict):
|
|
82
|
+
continue
|
|
83
|
+
|
|
84
|
+
related_model_label = rel_info.get("related_model", "")
|
|
85
|
+
if not related_model_label or "." not in related_model_label:
|
|
86
|
+
continue
|
|
87
|
+
|
|
88
|
+
target_app, target_model = related_model_label.split(".", 1)
|
|
89
|
+
|
|
90
|
+
target_table_name = rel_info.get("table_name", target_model.lower())
|
|
91
|
+
if target_app in all_models_data and target_model in all_models_data[target_app]:
|
|
92
|
+
target_table_name = all_models_data[target_app][target_model].get(
|
|
93
|
+
"table_name", target_model.lower()
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
target_entity_id = f"{target_app}__{target_table_name}"
|
|
97
|
+
|
|
98
|
+
rel_type_class = rel_info.get("type", "")
|
|
99
|
+
type_info = _get_relationship_type_and_description(rel_type_class)
|
|
100
|
+
if not type_info:
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
rel_type, description = type_info
|
|
104
|
+
|
|
105
|
+
relationships.append({
|
|
106
|
+
"source": source_entity_id,
|
|
107
|
+
"target": target_entity_id,
|
|
108
|
+
"source_model": source_model_name,
|
|
109
|
+
"target_model": target_model,
|
|
110
|
+
"type": rel_type,
|
|
111
|
+
"label": rel_name,
|
|
112
|
+
"description": description,
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
return relationships
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def generate_er_diagrams(models_data: dict[str, Any], docs_dir: Path) -> None:
|
|
119
|
+
"""Generate main ER diagram, app-specific diagrams, and index page from model data."""
|
|
120
|
+
generate_main_er_diagram(models_data, docs_dir)
|
|
121
|
+
|
|
122
|
+
for app_name, models in models_data.items():
|
|
123
|
+
if not isinstance(models, dict):
|
|
124
|
+
continue
|
|
125
|
+
generate_app_er_diagram(app_name, models, models_data, docs_dir)
|
|
126
|
+
|
|
127
|
+
generate_er_diagrams_index(models_data, docs_dir)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def generate_main_er_diagram(models_data: dict[str, Any], _docs_dir: Path) -> None:
|
|
131
|
+
"""Create main ER diagram showing all models and their relationships."""
|
|
132
|
+
entities = []
|
|
133
|
+
relationships = []
|
|
134
|
+
|
|
135
|
+
for app_name, models in models_data.items():
|
|
136
|
+
if not isinstance(models, dict):
|
|
137
|
+
continue
|
|
138
|
+
|
|
139
|
+
for model_name, model_info in models.items():
|
|
140
|
+
if not isinstance(model_info, dict):
|
|
141
|
+
continue
|
|
142
|
+
|
|
143
|
+
entity = _create_entity_from_model(app_name, model_name, model_info, include_fields=False)
|
|
144
|
+
entities.append(entity)
|
|
145
|
+
|
|
146
|
+
model_relationships = _process_model_relationships(
|
|
147
|
+
entity["id"], model_name, model_info, models_data
|
|
148
|
+
)
|
|
149
|
+
relationships.extend(model_relationships)
|
|
150
|
+
|
|
151
|
+
content = render_to_string(
|
|
152
|
+
"er_diagrams/main.html", {"entities": entities, "relationships": relationships}
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
write_file(f"{drf_to_mkdoc_settings.ER_DIAGRAMS_DIR}/main.md", content)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def generate_app_er_diagram(
|
|
159
|
+
app_name: str, app_models: dict[str, Any], all_models_data: dict[str, Any], _docs_dir: Path
|
|
160
|
+
) -> None:
|
|
161
|
+
"""Create app-specific ER diagram with detailed fields and related models."""
|
|
162
|
+
app_entities = []
|
|
163
|
+
related_entities = []
|
|
164
|
+
relationships = []
|
|
165
|
+
related_entity_ids = set()
|
|
166
|
+
|
|
167
|
+
for model_name, model_info in app_models.items():
|
|
168
|
+
if not isinstance(model_info, dict):
|
|
169
|
+
continue
|
|
170
|
+
|
|
171
|
+
entity = _create_entity_from_model(app_name, model_name, model_info, include_fields=True)
|
|
172
|
+
app_entities.append(entity)
|
|
173
|
+
|
|
174
|
+
model_relationships = _process_model_relationships(
|
|
175
|
+
entity["id"], model_name, model_info, all_models_data
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
for relationship in model_relationships:
|
|
179
|
+
target_entity_id = relationship["target"]
|
|
180
|
+
target_model = relationship["target_model"]
|
|
181
|
+
target_app = target_entity_id.split("__")[0]
|
|
182
|
+
|
|
183
|
+
if target_app != app_name and target_entity_id not in related_entity_ids:
|
|
184
|
+
if target_app in all_models_data and target_model in all_models_data[target_app]:
|
|
185
|
+
target_model_info = all_models_data[target_app][target_model]
|
|
186
|
+
related_entity = _create_entity_from_model(
|
|
187
|
+
target_app, target_model, target_model_info, include_fields=False
|
|
188
|
+
)
|
|
189
|
+
related_entities.append(related_entity)
|
|
190
|
+
related_entity_ids.add(target_entity_id)
|
|
191
|
+
|
|
192
|
+
relationships.append(relationship)
|
|
193
|
+
|
|
194
|
+
content = render_to_string(
|
|
195
|
+
"er_diagrams/app.html",
|
|
196
|
+
{
|
|
197
|
+
"app_name": app_name,
|
|
198
|
+
"app_entities": app_entities,
|
|
199
|
+
"related_entities": related_entities,
|
|
200
|
+
"relationships": relationships,
|
|
201
|
+
},
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
write_file(f"{drf_to_mkdoc_settings.ER_DIAGRAMS_DIR}/{app_name}.md", content)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def generate_er_diagrams_index(models_data: dict[str, Any], _docs_dir: Path) -> None:
|
|
208
|
+
"""Create index page listing all available ER diagrams with app summaries."""
|
|
209
|
+
apps = []
|
|
210
|
+
|
|
211
|
+
for app_name in sorted(models_data.keys()):
|
|
212
|
+
if not isinstance(models_data[app_name], dict):
|
|
213
|
+
continue
|
|
214
|
+
|
|
215
|
+
model_count = len([
|
|
216
|
+
m for m in models_data[app_name]
|
|
217
|
+
if isinstance(models_data[app_name][m], dict)
|
|
218
|
+
])
|
|
219
|
+
|
|
220
|
+
model_names = []
|
|
221
|
+
for model_name, model_info in models_data[app_name].items():
|
|
222
|
+
if isinstance(model_info, dict):
|
|
223
|
+
model_names.append(model_name)
|
|
224
|
+
if len(model_names) >= 3:
|
|
225
|
+
break
|
|
226
|
+
|
|
227
|
+
apps.append({"name": app_name, "model_count": model_count})
|
|
228
|
+
|
|
229
|
+
content = render_to_string("er_diagrams/index.html", {"apps": apps})
|
|
230
|
+
write_file(f"{drf_to_mkdoc_settings.ER_DIAGRAMS_DIR}/index.md", content)
|
drf_to_mkdoc/utils/schema.py
CHANGED
|
@@ -2,7 +2,7 @@ import inspect
|
|
|
2
2
|
import logging
|
|
3
3
|
from importlib import import_module
|
|
4
4
|
from types import SimpleNamespace
|
|
5
|
-
from typing import Any
|
|
5
|
+
from typing import Any, List
|
|
6
6
|
|
|
7
7
|
from drf_spectacular.openapi import AutoSchema as SpectacularAutoSchema
|
|
8
8
|
from drf_spectacular.plumbing import ComponentRegistry
|
|
@@ -208,6 +208,15 @@ class AutoSchema(SpectacularAutoSchema):
|
|
|
208
208
|
directly to the operation during schema generation instead of using a postprocessing hook.
|
|
209
209
|
"""
|
|
210
210
|
|
|
211
|
+
def __init__(self, *args, **kwargs):
|
|
212
|
+
self.tags = kwargs.pop("tags", [])
|
|
213
|
+
super().__init__()
|
|
214
|
+
|
|
215
|
+
def get_tags(self) -> List[str]:
|
|
216
|
+
if self.tags:
|
|
217
|
+
return self.tags
|
|
218
|
+
return super().get_tags()
|
|
219
|
+
|
|
211
220
|
def get_operation(
|
|
212
221
|
self,
|
|
213
222
|
path: str,
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: drf-to-mkdoc
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Generate Markdown API docs from Django/DRF OpenAPI schema for MkDocs
|
|
5
|
+
Author-email: Hossein Shayesteh <shayestehhs1@gmail.com>
|
|
6
|
+
Maintainer-email: Hossein Shayesteh <shayestehhs1@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/shayestehhs/drf-to-mkdoc
|
|
9
|
+
Project-URL: Repository, https://github.com/shayestehhs/drf-to-mkdoc
|
|
10
|
+
Project-URL: Documentation, https://github.com/shayestehhs/drf-to-mkdoc#readme
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/shayestehhs/drf-to-mkdoc/issues
|
|
12
|
+
Keywords: django,django-rest-framework,documentation,mkdocs,api
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Framework :: Django
|
|
24
|
+
Classifier: Framework :: Django :: 3.2
|
|
25
|
+
Classifier: Framework :: Django :: 4.0
|
|
26
|
+
Classifier: Framework :: Django :: 4.1
|
|
27
|
+
Classifier: Framework :: Django :: 4.2
|
|
28
|
+
Classifier: Framework :: Django :: 5.0
|
|
29
|
+
Classifier: Topic :: Documentation
|
|
30
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
31
|
+
Requires-Python: >=3.8
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
License-File: LICENSE
|
|
34
|
+
Requires-Dist: Django<6.0,>=3.2
|
|
35
|
+
Requires-Dist: djangorestframework<4.0,>=3.12
|
|
36
|
+
Requires-Dist: PyYAML>=6.0
|
|
37
|
+
Requires-Dist: drf-spectacular>=0.26.0
|
|
38
|
+
Requires-Dist: mkdocs>=1.4.0
|
|
39
|
+
Requires-Dist: mkdocs-material>=9.0.0
|
|
40
|
+
Requires-Dist: coreapi>=2.3.0
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
43
|
+
Requires-Dist: pytest-django>=4.5.0; extra == "dev"
|
|
44
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
45
|
+
Requires-Dist: isort>=5.10.0; extra == "dev"
|
|
46
|
+
Requires-Dist: flake8>=5.0.0; extra == "dev"
|
|
47
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
48
|
+
Dynamic: license-file
|
|
49
|
+
|
|
50
|
+
# DRF to MkDocs
|
|
51
|
+
|
|
52
|
+
Unlock effortless API documentation for your Django REST Framework project. Automatically generate beautiful, interactive, and maintainable docs that accelerate developer onboarding and streamline your team's workflow.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Why DRF to MkDocs?
|
|
57
|
+
|
|
58
|
+
`DRF to MkDocs` bridges the gap between your API's OpenAPI schema and user-friendly, maintainable documentation. It introspects your Django models and DRF views to automatically generate a polished, feature-rich documentation site that stays in sync with your codebase, empowering your team to build better APIs, faster.
|
|
59
|
+
|
|
60
|
+
- **Effortless Documentation**: Automate the entire process of generating and updating your API docs. Say goodbye to manual work and outdated information.
|
|
61
|
+
- **Accelerate Onboarding**: Provide new joiners with interactive, easy-to-navigate documentation. The "Try-it-out" feature and clear model relationships help them become productive from day one.
|
|
62
|
+
- **Deeply Integrated with DRF**: Leverages `drf-spectacular` for accurate schema generation, ensuring your documentation is a true reflection of your API.
|
|
63
|
+
- **Enhance Developer Experience**: Features like the interactive API console and in-depth model pages streamline development, testing, and debugging for the entire team.
|
|
64
|
+
- **Beautiful & Professional**: Built on MkDocs with the Material theme for a clean, modern, and responsive UI that you'll be proud to share.
|
|
65
|
+
|
|
66
|
+
## Gallery
|
|
67
|
+
|
|
68
|
+
<details>
|
|
69
|
+
<summary>🚀 Interactive Endpoint List & Filtering</summary>
|
|
70
|
+
<img width="1434" height="943" alt="List-EndPoint" src="https://github.com/user-attachments/assets/f886fc7f-afa0-4faa-b9c2-d6f754ca3597" />
|
|
71
|
+
</details>
|
|
72
|
+
|
|
73
|
+
<details>
|
|
74
|
+
<summary>🔬 Detailed Endpoint View with "Try-it-out"</summary>
|
|
75
|
+
<img width="958" height="887" alt="Detail-EndPoint" src="https://github.com/user-attachments/assets/9d9e3d4b-cb92-4ece-831e-aef45ceec768" />
|
|
76
|
+
<img width="532" height="804" alt="Try-it-out" src="https://github.com/user-attachments/assets/0f483922-60c4-4f62-8fb4-bc7372e82a03" />
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
<details>
|
|
80
|
+
<summary>📚 Rich Model Documentation</summary>
|
|
81
|
+
<img width="906" height="885" alt="Model-fields" src="https://github.com/user-attachments/assets/a1ca369c-ad40-4b05-83ec-ceb1f80aab23" />
|
|
82
|
+
<img width="848" height="886" alt="Model" src="https://github.com/user-attachments/assets/683d6d26-a8e4-4c05-8b5f-11a61a62cb0c" />
|
|
83
|
+
</details>
|
|
84
|
+
|
|
85
|
+
<details>
|
|
86
|
+
<summary>📈 Entity-Relationship Diagrams</summary>
|
|
87
|
+
<img width="953" height="606" alt="ER-Diagram" src="https://github.com/user-attachments/assets/3d0b1cb0-7ebf-4d4a-a181-1b7dbc9c6a01" />
|
|
88
|
+
</details>
|
|
89
|
+
|
|
90
|
+
## Key Features
|
|
91
|
+
|
|
92
|
+
| Feature | Description |
|
|
93
|
+
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
94
|
+
| 🚀 **Interactive API Console** | Test endpoints directly from the documentation with a "Try-it-out" feature, complete with a request builder and response viewer. |
|
|
95
|
+
| 🔍 **Advanced Filtering & Search** | Instantly find endpoints with multi-criteria filtering by app, method, path, and a real-time search. |
|
|
96
|
+
| 📚 **In-Depth Model Pages** | Automatically generate detailed pages for each model, including fields, relationships, choices, and methods. |
|
|
97
|
+
| 📊 **Entity-Relationship Diagrams** | Visualize model relationships with auto-generated, interactive ER diagrams for each app and for the entire project. |
|
|
98
|
+
| 🎨 **Modern & Responsive UI** | A beautiful and intuitive interface powered by MkDocs Material, featuring light/dark themes and full mobile support. |
|
|
99
|
+
| 🔧 **Highly Customizable** | Override templates, configure settings, and use custom functions to tailor the documentation to your project's specific needs. |
|
|
100
|
+
| ⚙️ **Simple Integration** | Works seamlessly with existing DRF projects and `drf-spectacular` without requiring complex setup. |
|
|
101
|
+
| 🤖 **AI-Powered Enhancements** | (Working on it...) Leverage AI to generate smarter examples and more descriptive documentation for your API. |
|
|
102
|
+
|
|
103
|
+
## Getting Started
|
|
104
|
+
|
|
105
|
+
### 1. Installation
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pip install drf-to-mkdoc
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 2. Configure Your Django Project
|
|
112
|
+
|
|
113
|
+
In your `settings.py`:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
# settings.py
|
|
117
|
+
|
|
118
|
+
INSTALLED_APPS = [
|
|
119
|
+
# ... your other apps
|
|
120
|
+
'drf_to_mkdoc',
|
|
121
|
+
'drf_spectacular', # Required for schema generation
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
# Required for OpenAPI schema generation
|
|
125
|
+
REST_FRAMEWORK = {
|
|
126
|
+
'DEFAULT_SCHEMA_CLASS': 'drf_to_mkdoc.utils.schema.AutoSchema',
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
SPECTACULAR_SETTINGS = {
|
|
130
|
+
'TITLE': 'Your API',
|
|
131
|
+
'DESCRIPTION': 'Your API description',
|
|
132
|
+
'VERSION': '1.0.0',
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# DRF to MkDocs specific settings
|
|
136
|
+
DRF_TO_MKDOC = {
|
|
137
|
+
'DJANGO_APPS': [
|
|
138
|
+
'users',
|
|
139
|
+
'products',
|
|
140
|
+
# ... list all apps you want to document
|
|
141
|
+
],
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 3. Create MkDocs Configuration
|
|
146
|
+
|
|
147
|
+
Create an `mkdocs.yml` file in your project root. You can start with the [default configuration](docs/mkdocs.yml) and customize it.
|
|
148
|
+
|
|
149
|
+
### 4. Build Your Documentation
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
python manage.py build_docs
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
For more detailed instructions, see the full [Installation and Setup Guide](docs/installation.md).
|
|
156
|
+
|
|
157
|
+
## Usage and Customization
|
|
158
|
+
|
|
159
|
+
### Building Your Documentation
|
|
160
|
+
|
|
161
|
+
To build the entire documentation site, run the following command. This will generate a static site in your `site/` directory.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
python manage.py build_docs
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
For more granular control, `DRF to MkDocs` provides several commands, such as `build_endpoint_docs` and `build_model_docs`.
|
|
168
|
+
|
|
169
|
+
### Serving Docs with Django
|
|
170
|
+
|
|
171
|
+
You can serve your documentation directly from your Django application, protecting it with Django's authentication system. This is ideal for private or internal APIs.
|
|
172
|
+
|
|
173
|
+
For a complete guide, see [Serving Docs with Django](docs/serving_docs_with_django.md).
|
|
174
|
+
|
|
175
|
+
### Customizing the OpenAPI Schema
|
|
176
|
+
|
|
177
|
+
`DRF to MkDocs` allows you to override and extend the auto-generated OpenAPI schema by providing a custom JSON file. This gives you fine-grained control over the final documentation, enabling you to add examples, descriptions, or even custom endpoints.
|
|
178
|
+
|
|
179
|
+
For more details, refer to the [Customizing Endpoints](docs/customizing_endpoints.md) guide.
|
|
180
|
+
|
|
181
|
+
### Best Practices
|
|
182
|
+
|
|
183
|
+
For better project organization, we recommend creating a separate `docs_settings.py` for documentation-specific configurations and using the `--settings` flag:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
python manage.py build_docs --settings=my_project.docs_settings
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
This keeps your production settings clean and your documentation configuration isolated.
|
|
190
|
+
|
|
191
|
+
## Configuration
|
|
192
|
+
|
|
193
|
+
You can customize the behavior of `DRF to MkDocs` by configuring the `DRF_TO_MKDOC` dictionary in your settings file.
|
|
194
|
+
|
|
195
|
+
| Key | Description | Default |
|
|
196
|
+
| -------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------- |
|
|
197
|
+
| `DJANGO_APPS` (required) | A list of Django app names to process. | `[]` |
|
|
198
|
+
| `DOCS_DIR` | The base directory where documentation will be generated. | `'docs'` |
|
|
199
|
+
| `ER_DIAGRAMS_DIR` | The directory for ER diagrams, relative to `DOCS_DIR`. | `'er_diagrams'` |
|
|
200
|
+
| `FIELD_GENERATORS` | Custom field value generators for creating better examples. | `{}` |
|
|
201
|
+
| `ENABLE_AI_DOCS` | A flag to enable AI-powered documentation features. | `False` |
|
|
202
|
+
| `PATH_PARAM_SUBSTITUTE_FUNCTION` | A custom function for substituting path parameters in URLs. | `None` |
|
|
203
|
+
| `PATH_PARAM_SUBSTITUTE_MAPPING` | A mapping for substituting common path parameters (e.g., `{'pk': 1}`). | `{}` |
|
|
204
|
+
|
|
205
|
+
## How It Works
|
|
206
|
+
|
|
207
|
+
`DRF to MkDocs` operates in a few stages:
|
|
208
|
+
|
|
209
|
+
1. **Model Introspection**: It deeply analyzes your Django models, mapping out their fields, relationships (like ForeignKeys and ManyToManyFields), and metadata.
|
|
210
|
+
2. **Schema Generation**: It uses `drf-spectacular` to generate a detailed OpenAPI schema for your API endpoints.
|
|
211
|
+
3. **Template Rendering**: It renders Jinja2 templates for each endpoint, model, and ER diagram, creating Markdown files.
|
|
212
|
+
4. **MkDocs Build**: Finally, it invokes MkDocs to build a static HTML site from the generated Markdown files.
|
|
213
|
+
|
|
214
|
+
This process ensures that your documentation is always an accurate and comprehensive reflection of your codebase.
|
|
215
|
+
|
|
216
|
+
## Contributing
|
|
217
|
+
|
|
218
|
+
Contributions are welcome! Whether it's a bug report, a new feature, or an improvement to the documentation, we appreciate your help. To ensure code quality, we use **CoderabbitAI** for automated code reviews on all pull requests.
|
|
219
|
+
|
|
220
|
+
Please see our [Contributing Guidelines](CONTRIBUTING.md) to get started.
|
|
221
|
+
|
|
222
|
+
### Development Setup
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
git clone https://github.com/Shayestehhs/drf-to-mkdoc.git
|
|
226
|
+
cd drf-to-mkdoc
|
|
227
|
+
pip install -e ".[dev]"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
drf_to_mkdoc/__init__.py,sha256=IbTW5uKQvJRG9ncHRuk_AGKHPn4ruxs5LqDpUFgUhws,180
|
|
2
2
|
drf_to_mkdoc/apps.py,sha256=-NrC_dRr6GmLmNQhkNh819B7V1SS4DYDv5JOR0TtuJM,560
|
|
3
3
|
drf_to_mkdoc/conf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
drf_to_mkdoc/conf/defaults.py,sha256=
|
|
5
|
-
drf_to_mkdoc/conf/settings.py,sha256=
|
|
4
|
+
drf_to_mkdoc/conf/defaults.py,sha256=5qbjvHvhhkQChRdy3tJvGRoJ1uXzBfoiHf71kt3a3XI,1072
|
|
5
|
+
drf_to_mkdoc/conf/settings.py,sha256=sxg3VIlhUkcxL1g-21E3FSuwqH4MfL9C3m2QwGw5rqA,5499
|
|
6
6
|
drf_to_mkdoc/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
drf_to_mkdoc/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
drf_to_mkdoc/management/commands/build_docs.py,sha256=k2N8i7sNWPJGVzUSdkDu47FleCSjIxClRq1dWBHwhjQ,4057
|
|
9
9
|
drf_to_mkdoc/management/commands/build_endpoint_docs.py,sha256=UcKoHFzmsEhs90kHMRvRe2XWx6xigrGAnwA5iEs839s,2450
|
|
10
|
-
drf_to_mkdoc/management/commands/build_model_docs.py,sha256=
|
|
10
|
+
drf_to_mkdoc/management/commands/build_model_docs.py,sha256=xVrsDXBG5FXviGPwr0t8atc6MibUxHRNu2rT3jBgyco,2336
|
|
11
11
|
drf_to_mkdoc/management/commands/extract_model_data.py,sha256=XoMO4C22ZPKQ99bh1WskEUT1JkA3GpDN5wb3_D5cN0I,13583
|
|
12
12
|
drf_to_mkdoc/management/commands/generate_doc_json.py,sha256=mWdYgMbSeLP4iQZeUm2DxwYQmdGy8w05XTEfbT_nOJo,19833
|
|
13
13
|
drf_to_mkdoc/management/commands/update_doc_schema.py,sha256=TtHVQxnVpB_VELRkVcdsDXDU5zXdguFleB1mXCDMAbg,2009
|
|
@@ -19,7 +19,7 @@ drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/form-manager.js,sha256=6KIe
|
|
|
19
19
|
drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/main.js,sha256=W0Vv9jdCturToACs_wapZ37ux0nRXy1d3GqfXq-0NuI,1821
|
|
20
20
|
drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/modal.js,sha256=IUg33Er2cF6qzIbxgnvlj8C_fSjNariyfFd3zswu3wU,14238
|
|
21
21
|
drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/query-parameters-extractor.js,sha256=3b6XshRFdf5TeZNktgxEBenEFWTTEsKjYZll0xMUv3Q,3542
|
|
22
|
-
drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/request-executor.js,sha256=
|
|
22
|
+
drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/request-executor.js,sha256=lBKP-GbUyXKhIGS1q0V0GxeJueRHTjfaDorIgB-LClg,12565
|
|
23
23
|
drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/response-modal.js,sha256=D8Xd9rEAJpMPExVxSmJ7PaQXCmIfRPhyv6t93A0AP0w,5671
|
|
24
24
|
drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/suggestions.js,sha256=WOXppK1HgYFDbVkCvchBKxL8rc_974roJAxZE2EBdDo,4396
|
|
25
25
|
drf_to_mkdoc/static/drf-to-mkdoc/javascripts/try-out/tabs.js,sha256=WwAjbisNap0lOQ3pZyWkW0G7hXvy_gFjHMCCPUu50a8,2791
|
|
@@ -71,6 +71,9 @@ drf_to_mkdoc/templates/endpoints/list/filters/app.html,sha256=vjY0GGg1UGKKb2JAIa
|
|
|
71
71
|
drf_to_mkdoc/templates/endpoints/list/filters/method.html,sha256=B9WHuuScIF45QRGv1wZVocCKMPUvyuEDg_gMaE02NXc,410
|
|
72
72
|
drf_to_mkdoc/templates/endpoints/list/filters/path.html,sha256=ZKq50BJu9AYdjiY2TXxhM8c8ivz6M8J_aZIC_q2gVvE,180
|
|
73
73
|
drf_to_mkdoc/templates/endpoints/list/filters/search.html,sha256=NbndD69M-iwFf-BXMo7rsHh1lrZnf6hiZGkPtGF1hU4,280
|
|
74
|
+
drf_to_mkdoc/templates/er_diagrams/app.html,sha256=4ptCVDrKKNMfW0mJbSQPYpe_wvJuNoRiL-uAg4uEYVc,749
|
|
75
|
+
drf_to_mkdoc/templates/er_diagrams/index.html,sha256=KxIpF-Krbbs6fIDdx52AS84sMs7L_pRjlnYklKNrD6s,429
|
|
76
|
+
drf_to_mkdoc/templates/er_diagrams/main.html,sha256=w0mA8Czb--B7FbQOyW6VCeGm1phMOzz2P9CAB4KK0po,657
|
|
74
77
|
drf_to_mkdoc/templates/model_detail/base.html,sha256=uJaGnFwfv68uJgWJA85Svs7MXPQ-dXi3-SJgR9GfiNM,731
|
|
75
78
|
drf_to_mkdoc/templates/model_detail/choices.html,sha256=-DAbUpr5jXL_e8r--KkdRXGZuF94_TuVmN17WQDltk0,304
|
|
76
79
|
drf_to_mkdoc/templates/model_detail/fields.html,sha256=dOYhfwFJThAuG65r8i6_A9budCTNsZ1pQRCGgAKdFAc,1163
|
|
@@ -84,11 +87,12 @@ drf_to_mkdoc/templates/try-out/modal.html,sha256=G3Ye6DntMVVYUnmbwkrf-YcYmw7AxtC
|
|
|
84
87
|
drf_to_mkdoc/templates/try-out/response-modal.html,sha256=mjt1bud07Y3BXp7716mQMlrv8xGRaQr4W2XRNKJWwGA,5980
|
|
85
88
|
drf_to_mkdoc/templatetags/custom_filters.py,sha256=b_0ExGgBKUIlNkJ8nXlc6mrhhiUUxtdq9thXH-yzEq4,3761
|
|
86
89
|
drf_to_mkdoc/utils/__init__.py,sha256=6dFTb07S6yIf-INMy0Mlgf5purNir687ZU9WZtITh4k,68
|
|
87
|
-
drf_to_mkdoc/utils/endpoint_detail_generator.py,sha256=
|
|
90
|
+
drf_to_mkdoc/utils/endpoint_detail_generator.py,sha256=toZ3JWlVHtsYPJLG8ZDvLYtfsbNr3P-YEINKpOElwQ4,28391
|
|
88
91
|
drf_to_mkdoc/utils/endpoint_list_generator.py,sha256=yVX7qVUTuKF3TPFgm6FI-vVsVZQ7XHMXmZZalgSN8pk,3579
|
|
92
|
+
drf_to_mkdoc/utils/er_diagram_generator.py,sha256=9X4L2XPVSKwxHZQspOSMg7TacAzImeXGgYPzhlsL-U8,7962
|
|
89
93
|
drf_to_mkdoc/utils/model_detail_generator.py,sha256=_ac2PYSzSwRUgUn-J-nmg7mfQGn8SU_4vkMpMRIxgEU,2619
|
|
90
94
|
drf_to_mkdoc/utils/model_list_generator.py,sha256=Ki-CwIYKmUbPm3_jUPLPosPfppyVLrZMkqbuPPO3Ycw,1988
|
|
91
|
-
drf_to_mkdoc/utils/schema.py,sha256=
|
|
95
|
+
drf_to_mkdoc/utils/schema.py,sha256=vVLnnVt3ANaHSAdrsjOEfkakZZufeR5PUSuo2dyR4vU,10311
|
|
92
96
|
drf_to_mkdoc/utils/ai_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
93
97
|
drf_to_mkdoc/utils/ai_tools/enums.py,sha256=K39bJjHgXwNst2NL6z-5bztW3ZU5iCxg2b0KEodD6eM,238
|
|
94
98
|
drf_to_mkdoc/utils/ai_tools/exceptions.py,sha256=yFauOtuSRGRnQt41u2qCMvWEbN0eblgKwXuH-GX3Wbk,634
|
|
@@ -105,8 +109,8 @@ drf_to_mkdoc/utils/commons/path_utils.py,sha256=Pi9g1xXDPsRzmn4kTeNSVtXG9v6n1h2Z
|
|
|
105
109
|
drf_to_mkdoc/utils/commons/schema_utils.py,sha256=1mQxzo08J6tlVmTIJ0hCQ6wCZUWMuV82POhLWUfOYtI,7567
|
|
106
110
|
drf_to_mkdoc/utils/extractors/__init__.py,sha256=BvC8gKOPVI9gU1Piw0jRhKQ2ER5s1moAxgq7ZYkJWNI,86
|
|
107
111
|
drf_to_mkdoc/utils/extractors/query_parameter_extractors.py,sha256=xELPYI6tcqfkxOa475JPMaxRzRGUX--Z9oYRlKgXb7w,7964
|
|
108
|
-
drf_to_mkdoc-0.
|
|
109
|
-
drf_to_mkdoc-0.
|
|
110
|
-
drf_to_mkdoc-0.
|
|
111
|
-
drf_to_mkdoc-0.
|
|
112
|
-
drf_to_mkdoc-0.
|
|
112
|
+
drf_to_mkdoc-0.3.1.dist-info/licenses/LICENSE,sha256=3n9_ckIREsH8ogCxWW6dFsw_WfGcluG2mHcgl9i_UU0,1068
|
|
113
|
+
drf_to_mkdoc-0.3.1.dist-info/METADATA,sha256=vsGgQCWq3UUXiVIPrNo8DvyKkkFxXiolEVmtZNu2iwI,11692
|
|
114
|
+
drf_to_mkdoc-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
115
|
+
drf_to_mkdoc-0.3.1.dist-info/top_level.txt,sha256=ZzJecR6j_tvLZiubUBEgawHflozC4DQy9ooNf1yDJ3Q,13
|
|
116
|
+
drf_to_mkdoc-0.3.1.dist-info/RECORD,,
|
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: drf-to-mkdoc
|
|
3
|
-
Version: 0.2.4
|
|
4
|
-
Summary: Generate Markdown API docs from Django/DRF OpenAPI schema for MkDocs
|
|
5
|
-
Author-email: Hossein Shayesteh <shayestehhs1@gmail.com>
|
|
6
|
-
Maintainer-email: Hossein Shayesteh <shayestehhs1@gmail.com>
|
|
7
|
-
License: MIT
|
|
8
|
-
Project-URL: Homepage, https://github.com/shayestehhs/drf-to-mkdoc
|
|
9
|
-
Project-URL: Repository, https://github.com/shayestehhs/drf-to-mkdoc
|
|
10
|
-
Project-URL: Documentation, https://github.com/shayestehhs/drf-to-mkdoc#readme
|
|
11
|
-
Project-URL: Bug Tracker, https://github.com/shayestehhs/drf-to-mkdoc/issues
|
|
12
|
-
Keywords: django,django-rest-framework,documentation,mkdocs,api
|
|
13
|
-
Classifier: Development Status :: 4 - Beta
|
|
14
|
-
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
-
Classifier: Operating System :: OS Independent
|
|
17
|
-
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
-
Classifier: Framework :: Django
|
|
24
|
-
Classifier: Framework :: Django :: 3.2
|
|
25
|
-
Classifier: Framework :: Django :: 4.0
|
|
26
|
-
Classifier: Framework :: Django :: 4.1
|
|
27
|
-
Classifier: Framework :: Django :: 4.2
|
|
28
|
-
Classifier: Framework :: Django :: 5.0
|
|
29
|
-
Classifier: Topic :: Documentation
|
|
30
|
-
Classifier: Topic :: Software Development :: Documentation
|
|
31
|
-
Requires-Python: >=3.8
|
|
32
|
-
Description-Content-Type: text/markdown
|
|
33
|
-
License-File: LICENSE
|
|
34
|
-
Requires-Dist: Django<6.0,>=3.2
|
|
35
|
-
Requires-Dist: djangorestframework<4.0,>=3.12
|
|
36
|
-
Requires-Dist: PyYAML>=6.0
|
|
37
|
-
Requires-Dist: drf-spectacular>=0.26.0
|
|
38
|
-
Requires-Dist: mkdocs>=1.4.0
|
|
39
|
-
Requires-Dist: mkdocs-material>=9.0.0
|
|
40
|
-
Requires-Dist: coreapi>=2.3.0
|
|
41
|
-
Provides-Extra: dev
|
|
42
|
-
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
43
|
-
Requires-Dist: pytest-django>=4.5.0; extra == "dev"
|
|
44
|
-
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
45
|
-
Requires-Dist: isort>=5.10.0; extra == "dev"
|
|
46
|
-
Requires-Dist: flake8>=5.0.0; extra == "dev"
|
|
47
|
-
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
48
|
-
Dynamic: license-file
|
|
49
|
-
|
|
50
|
-
# DRF to MkDocs
|
|
51
|
-
|
|
52
|
-
Generate beautiful, interactive Markdown API documentation from Django REST Framework OpenAPI schema for MkDocs.
|
|
53
|
-
|
|
54
|
-
## Why you'll love it
|
|
55
|
-
|
|
56
|
-
- **Zero-hassle docs**: Beautiful, always-in-sync API docs straight from your codebase
|
|
57
|
-
- **Model deep dive**: Auto-generated model pages with fields, relationships, and choices
|
|
58
|
-
- **Lightning-fast discovery**: Interactive endpoint index with powerful filters and search
|
|
59
|
-
- **Try-it-out**: Interactive API testing directly in the documentation with request/response examples
|
|
60
|
-
- **AI-powered**: Optional AI-generated documentation with custom field generators(Wait for it...)
|
|
61
|
-
- **DRF-native**: Works with DRF Spectacular; no custom schema wiring needed
|
|
62
|
-
- **MkDocs Material**: Looks great out of the box with the Material theme
|
|
63
|
-
|
|
64
|
-
## Installation
|
|
65
|
-
|
|
66
|
-
See the full installation guide in `docs/installation.md`.
|
|
67
|
-
|
|
68
|
-
## Quick Start
|
|
69
|
-
|
|
70
|
-
1. **Configure your Django project**:
|
|
71
|
-
|
|
72
|
-
```python
|
|
73
|
-
# settings.py
|
|
74
|
-
INSTALLED_APPS = [
|
|
75
|
-
# ... your other apps
|
|
76
|
-
'drf_to_mkdoc',
|
|
77
|
-
]
|
|
78
|
-
|
|
79
|
-
# Required for OpenAPI schema generation
|
|
80
|
-
REST_FRAMEWORK = {
|
|
81
|
-
'DEFAULT_SCHEMA_CLASS': 'drf_to_mkdoc.utils.schema.AutoSchema',
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
SPECTACULAR_SETTINGS = {
|
|
85
|
-
'TITLE': 'Your API',
|
|
86
|
-
'DESCRIPTION': 'Your API description',
|
|
87
|
-
'VERSION': '1.0.0',
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
DRF_TO_MKDOC = {
|
|
92
|
-
'DJANGO_APPS': [
|
|
93
|
-
'users',
|
|
94
|
-
'products',
|
|
95
|
-
'orders',
|
|
96
|
-
'inventory',
|
|
97
|
-
],
|
|
98
|
-
# Optional: Override default paths
|
|
99
|
-
# 'DOCS_DIR': 'docs',
|
|
100
|
-
# 'CONFIG_DIR': 'docs/configs',
|
|
101
|
-
# 'MODEL_DOCS_FILE': 'docs/model-docs.json',
|
|
102
|
-
# 'DOC_CONFIG_FILE': 'docs/configs/doc_config.json',
|
|
103
|
-
# 'CUSTOM_SCHEMA_FILE': 'docs/configs/custom_schema.json',
|
|
104
|
-
# 'FIELD_GENERATORS': {
|
|
105
|
-
# 'email': 'faker.email',
|
|
106
|
-
# 'name': 'faker.name',
|
|
107
|
-
# 'created_at': 'datetime.now',
|
|
108
|
-
# },
|
|
109
|
-
# 'ENABLE_AI_DOCS': False,
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
2. **Create MkDocs configuration**:
|
|
114
|
-
Copy the [`docs/mkdocs.yml`](docs/mkdocs.yml) file to your project root and customize it as needed.
|
|
115
|
-
|
|
116
|
-
3. **Build documentation**:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
python manage.py build_docs --settings=docs_settings
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Configuration Options
|
|
123
|
-
|
|
124
|
-
The `DRF_TO_MKDOC` setting supports several configuration options:
|
|
125
|
-
|
|
126
|
-
- **`DJANGO_APPS`** (required): List of Django app names to process
|
|
127
|
-
- **`DOCS_DIR`**: Directory where docs will be generated (default: `docs`)
|
|
128
|
-
- **`CONFIG_DIR`**: Directory for configuration files (default: `docs/configs`)
|
|
129
|
-
- **`FIELD_GENERATORS`**: Custom field value generators for better examples
|
|
130
|
-
- **`ENABLE_AI_DOCS`**: Enable AI-powered documentation features (default: `False`)
|
|
131
|
-
- **`PATH_PARAM_SUBSTITUTE_FUNCTION`**: Custom function for path parameter substitution
|
|
132
|
-
- **`PATH_PARAM_SUBSTITUTE_MAPPING`**: Mapping for path parameter substitution
|
|
133
|
-
|
|
134
|
-
## Available Commands
|
|
135
|
-
|
|
136
|
-
- `build_docs`: Build the complete documentation site with MkDocs
|
|
137
|
-
- `build_endpoint_docs`: Build endpoint documentation from OpenAPI schema
|
|
138
|
-
- `build_model_docs`: Build model documentation from model JSON data
|
|
139
|
-
- `extract_model_data`: Extract model data from Django model introspection and save as JSON
|
|
140
|
-
- `generate_doc_json`: Generate JSON context for new API endpoints to be documented
|
|
141
|
-
- `update_doc_schema`: Update the final schema by copying the documented schema
|
|
142
|
-
|
|
143
|
-
## What you get
|
|
144
|
-
|
|
145
|
-
See a detailed overview of generated files in `docs/structure.md` and a feature breakdown in `docs/features.md`.
|
|
146
|
-
|
|
147
|
-
## Key Features
|
|
148
|
-
|
|
149
|
-
### 🚀 Interactive API Testing (Try-Out)
|
|
150
|
-
- **Live API testing**: Test endpoints directly from the documentation
|
|
151
|
-
- **Request builder**: Interactive forms for parameters, headers, and request body
|
|
152
|
-
- **Response viewer**: Real-time response display with syntax highlighting
|
|
153
|
-
- **Floating action button**: Easy access to testing interface
|
|
154
|
-
- **Multiple examples**: Support for both empty and populated response examples
|
|
155
|
-
|
|
156
|
-
### 🤖 AI-Powered Documentation
|
|
157
|
-
- **Custom field generators**: Define custom value generators for specific fields
|
|
158
|
-
- **AI documentation**: Optional AI-generated documentation with context analysis
|
|
159
|
-
- **Smart examples**: Enhanced example generation for better API understanding
|
|
160
|
-
|
|
161
|
-
### 📊 Advanced Filtering & Search
|
|
162
|
-
- **Multi-criteria filtering**: Filter by app, HTTP method, path, and search terms
|
|
163
|
-
- **Real-time search**: Instant search across all endpoints
|
|
164
|
-
- **Smart suggestions**: Auto-complete for query parameters and field names
|
|
165
|
-
|
|
166
|
-
### 🎨 Beautiful UI
|
|
167
|
-
- **Material Design**: Modern, responsive interface with dark/light themes
|
|
168
|
-
- **Interactive elements**: Hover effects, animations, and smooth transitions
|
|
169
|
-
- **Mobile-friendly**: Fully responsive design for all devices
|
|
170
|
-
|
|
171
|
-
## How it works
|
|
172
|
-
|
|
173
|
-
Under the hood, drf-to-mkdoc introspects your models and reads your DRF OpenAPI schema to generate clean, organized Markdown. Then MkDocs turns it into a polished static site. Always current, no manual updates.
|
|
174
|
-
|
|
175
|
-
## Explore more
|
|
176
|
-
|
|
177
|
-
- Customizing endpoint docs: `docs/customizing_endpoints.md`
|
|
178
|
-
- Serving docs through Django (with permissions): `docs/serving_mkdocs_with_django.md`
|
|
179
|
-
|
|
180
|
-
## Dependencies
|
|
181
|
-
|
|
182
|
-
- Django >= 3.2, < 6.0
|
|
183
|
-
- Django REST Framework >= 3.12, < 4.0
|
|
184
|
-
- drf-spectacular >= 0.26.0
|
|
185
|
-
- PyYAML >= 6.0
|
|
186
|
-
- MkDocs >= 1.4.0
|
|
187
|
-
- MkDocs Material >= 9.0.0
|
|
188
|
-
- coreapi >= 2.3.0
|
|
189
|
-
|
|
190
|
-
## Development
|
|
191
|
-
|
|
192
|
-
### Setup Development Environment
|
|
193
|
-
|
|
194
|
-
```bash
|
|
195
|
-
git clone https://github.com/Shayestehhs/drf-to-mkdoc.git
|
|
196
|
-
cd drf-to-mkdoc
|
|
197
|
-
pip install -e ".[dev]"
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
## Project Structure
|
|
201
|
-
|
|
202
|
-
```
|
|
203
|
-
drf-to-mkdoc/
|
|
204
|
-
├── drf_to_mkdoc/
|
|
205
|
-
│ ├── conf/
|
|
206
|
-
│ │ ├── defaults.py # Default configuration values
|
|
207
|
-
│ │ └── settings.py # Settings management
|
|
208
|
-
│ ├── management/
|
|
209
|
-
│ │ └── commands/
|
|
210
|
-
│ │ ├── build_docs.py # Build MkDocs site
|
|
211
|
-
│ │ ├── build_endpoint_docs.py # Build endpoint documentation
|
|
212
|
-
│ │ ├── build_model_docs.py # Build model documentation
|
|
213
|
-
│ │ ├── extract_model_data.py # Extract model data from Django
|
|
214
|
-
│ │ ├── generate_doc_json.py # Generate JSON context for AI docs
|
|
215
|
-
│ │ └── update_doc_schema.py # Schema updates
|
|
216
|
-
│ ├── static/
|
|
217
|
-
│ │ └── drf-to-mkdoc/
|
|
218
|
-
│ │ ├── javascripts/
|
|
219
|
-
│ │ │ ├── try-out/ # Interactive API testing
|
|
220
|
-
│ │ │ └── endpoints-filter.js # Endpoint filtering
|
|
221
|
-
│ │ └── stylesheets/ # CSS for styling
|
|
222
|
-
│ ├── templates/
|
|
223
|
-
│ │ ├── endpoints/ # Endpoint documentation templates
|
|
224
|
-
│ │ ├── model_detail/ # Model documentation templates
|
|
225
|
-
│ │ └── try-out/ # Interactive testing templates
|
|
226
|
-
│ └── utils/
|
|
227
|
-
│ ├── ai_tools/ # AI-powered documentation features
|
|
228
|
-
│ ├── commons/ # Shared utilities
|
|
229
|
-
│ ├── extractors/ # Query parameter extraction
|
|
230
|
-
│ ├── endpoint_detail_generator.py
|
|
231
|
-
│ ├── endpoint_list_generator.py
|
|
232
|
-
│ ├── model_detail_generator.py
|
|
233
|
-
│ ├── model_list_generator.py
|
|
234
|
-
│ └── schema.py
|
|
235
|
-
├── docs/ # Generated documentation
|
|
236
|
-
├── pyproject.toml # Project configuration
|
|
237
|
-
└── README.md
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## License
|
|
241
|
-
|
|
242
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
243
|
-
|
|
244
|
-
## Recommendations
|
|
245
|
-
|
|
246
|
-
### .gitignore Configuration
|
|
247
|
-
|
|
248
|
-
To avoid committing generated files to your repository, add the following to your `.gitignore` file:
|
|
249
|
-
|
|
250
|
-
```gitignore
|
|
251
|
-
# Documentation
|
|
252
|
-
/docs/endpoints/
|
|
253
|
-
/docs/models/
|
|
254
|
-
/docs/configs/doc-schema.yaml
|
|
255
|
-
|
|
256
|
-
# Build artifacts
|
|
257
|
-
/site/
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
This will ensure that only the source configuration and scripts are versioned, while the generated documentation is excluded.
|
|
261
|
-
|
|
262
|
-
### docs_settings.py Best Practices
|
|
263
|
-
|
|
264
|
-
Create a separate `docs_settings.py` file that inherits from your main settings:
|
|
265
|
-
|
|
266
|
-
```python
|
|
267
|
-
# docs_settings.py
|
|
268
|
-
from .settings import *
|
|
269
|
-
|
|
270
|
-
DRF_TO_MKDOC = {
|
|
271
|
-
'DJANGO_APPS': ['your_app1', 'your_app2'],
|
|
272
|
-
}
|
|
273
|
-
# Other doc settings...
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
Then use the `--settings` argument when running the build command:
|
|
277
|
-
|
|
278
|
-
```bash
|
|
279
|
-
python manage.py build_docs --settings=docs_settings
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
### Project Organization
|
|
283
|
-
|
|
284
|
-
```
|
|
285
|
-
your-project/
|
|
286
|
-
├── settings.py # Main Django settings
|
|
287
|
-
├── docs_settings.py # Documentation-specific settings
|
|
288
|
-
├── mkdocs.yml # MkDocs configuration
|
|
289
|
-
├── docs/ # Generated documentation (gitignored)
|
|
290
|
-
└── site/ # Built site (gitignored)
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Contributing
|
|
294
|
-
|
|
295
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed contribution guidelines.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|