nadoc 0.1.0__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.
- nadoc-0.1.0/LICENSE +21 -0
- nadoc-0.1.0/PKG-INFO +238 -0
- nadoc-0.1.0/README.md +198 -0
- nadoc-0.1.0/pyproject.toml +105 -0
- nadoc-0.1.0/setup.cfg +4 -0
- nadoc-0.1.0/src/nadoc/__init__.py +9 -0
- nadoc-0.1.0/src/nadoc/__main__.py +3 -0
- nadoc-0.1.0/src/nadoc/api.py +109 -0
- nadoc-0.1.0/src/nadoc/assets/fonts/Inter-LICENSE.txt +92 -0
- nadoc-0.1.0/src/nadoc/assets/fonts/InterVariable.woff2 +0 -0
- nadoc-0.1.0/src/nadoc/assets/fonts/JetBrainsMono-OFL.txt +93 -0
- nadoc-0.1.0/src/nadoc/assets/fonts/JetBrainsMono-Regular.woff2 +0 -0
- nadoc-0.1.0/src/nadoc/assets/icons/csharp.svg +1 -0
- nadoc-0.1.0/src/nadoc/assets/icons/curl.svg +7 -0
- nadoc-0.1.0/src/nadoc/assets/icons/go.svg +1 -0
- nadoc-0.1.0/src/nadoc/assets/icons/java.svg +1 -0
- nadoc-0.1.0/src/nadoc/assets/icons/javascript.svg +1 -0
- nadoc-0.1.0/src/nadoc/assets/icons/json.svg +1 -0
- nadoc-0.1.0/src/nadoc/assets/icons/node.svg +1 -0
- nadoc-0.1.0/src/nadoc/assets/icons/php.svg +1 -0
- nadoc-0.1.0/src/nadoc/assets/icons/python.svg +1 -0
- nadoc-0.1.0/src/nadoc/assets/nada.css +172 -0
- nadoc-0.1.0/src/nadoc/assets/nada.js +234 -0
- nadoc-0.1.0/src/nadoc/cli.py +66 -0
- nadoc-0.1.0/src/nadoc/code_samples/__init__.py +5 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/__init__.py +0 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/csharp.py +47 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/curl.py +23 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/go.py +49 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/java.py +40 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/javascript.py +36 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/node.py +34 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/php.py +44 -0
- nadoc-0.1.0/src/nadoc/code_samples/generators/python.py +37 -0
- nadoc-0.1.0/src/nadoc/code_samples/model.py +32 -0
- nadoc-0.1.0/src/nadoc/code_samples/registry.py +44 -0
- nadoc-0.1.0/src/nadoc/code_samples/utils.py +58 -0
- nadoc-0.1.0/src/nadoc/compatibility.py +151 -0
- nadoc-0.1.0/src/nadoc/config/__init__.py +17 -0
- nadoc-0.1.0/src/nadoc/config/loader.py +190 -0
- nadoc-0.1.0/src/nadoc/config/model.py +57 -0
- nadoc-0.1.0/src/nadoc/config/presets.py +159 -0
- nadoc-0.1.0/src/nadoc/config/theme.py +34 -0
- nadoc-0.1.0/src/nadoc/diagnostics.py +27 -0
- nadoc-0.1.0/src/nadoc/errors.py +2 -0
- nadoc-0.1.0/src/nadoc/loader.py +42 -0
- nadoc-0.1.0/src/nadoc/model.py +171 -0
- nadoc-0.1.0/src/nadoc/normalization/__init__.py +0 -0
- nadoc-0.1.0/src/nadoc/normalization/common.py +156 -0
- nadoc-0.1.0/src/nadoc/normalization/context.py +30 -0
- nadoc-0.1.0/src/nadoc/normalization/markdown.py +111 -0
- nadoc-0.1.0/src/nadoc/normalization/parameters.py +109 -0
- nadoc-0.1.0/src/nadoc/normalization/responses.py +134 -0
- nadoc-0.1.0/src/nadoc/normalization/schemas.py +243 -0
- nadoc-0.1.0/src/nadoc/normalization/security.py +130 -0
- nadoc-0.1.0/src/nadoc/normalize.py +328 -0
- nadoc-0.1.0/src/nadoc/overlay.py +68 -0
- nadoc-0.1.0/src/nadoc/references.py +29 -0
- nadoc-0.1.0/src/nadoc/render.py +163 -0
- nadoc-0.1.0/src/nadoc/request_example.py +157 -0
- nadoc-0.1.0/src/nadoc/schema_keywords.py +5 -0
- nadoc-0.1.0/src/nadoc/templates/page.html.j2 +187 -0
- nadoc-0.1.0/src/nadoc/templates/schema.html.j2 +55 -0
- nadoc-0.1.0/src/nadoc.egg-info/PKG-INFO +238 -0
- nadoc-0.1.0/src/nadoc.egg-info/SOURCES.txt +75 -0
- nadoc-0.1.0/src/nadoc.egg-info/dependency_links.txt +1 -0
- nadoc-0.1.0/src/nadoc.egg-info/entry_points.txt +2 -0
- nadoc-0.1.0/src/nadoc.egg-info/requires.txt +15 -0
- nadoc-0.1.0/src/nadoc.egg-info/top_level.txt +1 -0
- nadoc-0.1.0/tests/test_cli.py +125 -0
- nadoc-0.1.0/tests/test_code_samples.py +186 -0
- nadoc-0.1.0/tests/test_compatibility.py +162 -0
- nadoc-0.1.0/tests/test_config.py +463 -0
- nadoc-0.1.0/tests/test_openapi_features.py +684 -0
- nadoc-0.1.0/tests/test_overlay.py +106 -0
- nadoc-0.1.0/tests/test_parameters_and_examples.py +350 -0
- nadoc-0.1.0/tests/test_rendering.py +589 -0
nadoc-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ibudidi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
nadoc-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nadoc
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A simple static documentation generator for OpenAPI 3.1 specs
|
|
5
|
+
Author-email: Ibudidi <ibudidi@users.noreply.github.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ibudidi/nadoc
|
|
8
|
+
Project-URL: Repository, https://github.com/ibudidi/nadoc
|
|
9
|
+
Project-URL: Issues, https://github.com/ibudidi/nadoc/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/ibudidi/nadoc/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: openapi,documentation,static-site,api
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Documentation
|
|
22
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: Jinja2<4,>=3.1
|
|
27
|
+
Requires-Dist: markdown-it-py<5,>=3
|
|
28
|
+
Requires-Dist: Pygments<3,>=2.19
|
|
29
|
+
Requires-Dist: PyYAML<7,>=6
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: build<2,>=1; extra == "dev"
|
|
32
|
+
Requires-Dist: pip-audit<3,>=2.7; extra == "dev"
|
|
33
|
+
Requires-Dist: pyright<2,>=1.1; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff<1,>=0.9; extra == "dev"
|
|
35
|
+
Requires-Dist: setuptools>=83; extra == "dev"
|
|
36
|
+
Requires-Dist: twine<7,>=6; extra == "dev"
|
|
37
|
+
Provides-Extra: fonts
|
|
38
|
+
Requires-Dist: fonttools[woff]<5,>=4.53; extra == "fonts"
|
|
39
|
+
Dynamic: license-file
|
|
40
|
+
|
|
41
|
+
# Nadoc
|
|
42
|
+
|
|
43
|
+
Deterministic static documentation for OpenAPI.
|
|
44
|
+
|
|
45
|
+
Nadoc converts an OpenAPI 3.1 document and an optional OpenAPI Overlay 1.x document into a self-contained,
|
|
46
|
+
server-rendered API documentation site. CSS, JavaScript, and language icons are embedded in the generated HTML;
|
|
47
|
+
Python is only required at generation time.
|
|
48
|
+
|
|
49
|
+
> Nadoc's renderer profile is tested and explicitly documented. Strict mode rejects known unsupported semantics rather
|
|
50
|
+
> than silently omitting them.
|
|
51
|
+
|
|
52
|
+
## Requirements
|
|
53
|
+
|
|
54
|
+
- Python 3.10 or newer
|
|
55
|
+
- An OpenAPI 3.0 or 3.1 YAML or JSON document
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
For an isolated command-line installation from PyPI:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pipx install nadoc
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Alternatively, install Nadoc into the active Python environment:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
python3 -m pip install nadoc
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
From this source checkout:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
python3 -m pip install .
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Quick start
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
nadoc openapi.yaml --output-dir api-docs
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Open `api-docs/index.html` in a browser. The generated HTML embeds Nadoc's CSS, JavaScript, language icons, and Latin
|
|
84
|
+
subsets of Inter and JetBrains Mono, so viewing it does not require network resources. Run `nadoc --help` for all command-line options.
|
|
85
|
+
|
|
86
|
+
## Configuration
|
|
87
|
+
|
|
88
|
+
Apply an optional overlay:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
nadoc openapi.yaml \
|
|
92
|
+
--overlay documentation-overlay.yaml \
|
|
93
|
+
--output-dir api-docs
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The HTML shell is minified by default; pass `--no-minify` (or `output.minify: false`) to keep the indented layout.
|
|
97
|
+
Embedded code and assets are never altered by minification. To keep the single file small, Nadoc ships Latin-subset
|
|
98
|
+
fonts, draws repeated icons from CSS masks instead of inline SVG, and compacts syntax-highlighted samples.
|
|
99
|
+
|
|
100
|
+
Customize the generated theme with a versioned Nadoc configuration:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
# nadoc.yaml
|
|
104
|
+
version: 1
|
|
105
|
+
input:
|
|
106
|
+
spec: ./openapi.yaml
|
|
107
|
+
overlay: ./overlay.yaml
|
|
108
|
+
strict: true
|
|
109
|
+
site:
|
|
110
|
+
title: Acme API
|
|
111
|
+
product_name: Developer Platform
|
|
112
|
+
language: en
|
|
113
|
+
theme:
|
|
114
|
+
default: system
|
|
115
|
+
preset: night-owl
|
|
116
|
+
colors:
|
|
117
|
+
primary: "#2563eb"
|
|
118
|
+
code_samples:
|
|
119
|
+
languages: [curl, python, javascript]
|
|
120
|
+
output:
|
|
121
|
+
directory: ./api-docs
|
|
122
|
+
html_file: index.html
|
|
123
|
+
spec_file: openapi.yaml
|
|
124
|
+
emit_spec: true
|
|
125
|
+
minify: true
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
nadoc --config nadoc.yaml
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Config version 1 supports `input.spec`, `input.overlay`, `input.strict`, `site.title`, `site.product_name`,
|
|
133
|
+
`site.language`, `theme.default`, `theme.preset`, `theme.colors.primary`, `code_samples.languages`, `output.directory`,
|
|
134
|
+
`output.html_file`, `output.spec_file`, `output.emit_spec`, and `output.minify`. Relative input and output paths are resolved from the directory containing
|
|
135
|
+
the config file, so `nadoc --config nadoc.yaml` is independent of the current working directory.
|
|
136
|
+
|
|
137
|
+
`code_samples.languages` controls which request examples Nadoc generates and their order after authored `x-codeSamples`. Supported values are
|
|
138
|
+
`curl`, `python`, `javascript`, `node`, `go`, `java`, `php`, and `csharp`. All are generated by default for backward
|
|
139
|
+
compatibility. Use an empty list (`languages: []`) to disable generated examples; authored OpenAPI `x-codeSamples`
|
|
140
|
+
remain available.
|
|
141
|
+
|
|
142
|
+
The default display mode may be `system`, `light`, or `dark`. Presets include the dark themes `atom-one-dark`,
|
|
143
|
+
`dracula`, `night-owl`, `catppuccin-dark`, and `ayu-dark`, plus the light themes `atom-one-light`,
|
|
144
|
+
`bracket-light-pro`, `bluloco-light`, `catppuccin-light`, and `ayu-light`. The Atom One, Catppuccin, and Ayu presets are paired:
|
|
145
|
+
either variant styles both display modes, while the preset name selects the initial mode. When
|
|
146
|
+
`theme.default` is omitted, a preset selects its native light or dark mode. The theme toggle remains available and
|
|
147
|
+
uses Nadoc's neutral palette for the opposite mode except when a paired Atom One, Catppuccin, or Ayu preset is selected.
|
|
148
|
+
|
|
149
|
+
The primary color must use `#RRGGBB` notation. It overrides a preset's primary and accent colors and Nadoc derives
|
|
150
|
+
appropriate light and dark brand shades from it. Elevation shadows are always neutral grey/black and never inherit
|
|
151
|
+
the primary color, so unusual or red brand colors do not tint cards and panels.
|
|
152
|
+
The header brand mark uses the first non-whitespace character of the configured title, falling back to the OpenAPI
|
|
153
|
+
`info.title`.
|
|
154
|
+
|
|
155
|
+
Explicit command-line or Python API values override config values, which override Nadoc defaults. Boolean CLI
|
|
156
|
+
options support both forms, such as `--minify`/`--no-minify`, `--strict`/`--no-strict`, and
|
|
157
|
+
`--emit-spec`/`--no-emit-spec`. Output file settings accept file names only; place them using `output.directory`.
|
|
158
|
+
Other sections from the proposed v1 schema are reserved for future releases and are rejected rather than silently
|
|
159
|
+
ignored.
|
|
160
|
+
|
|
161
|
+
Generated files:
|
|
162
|
+
|
|
163
|
+
```text
|
|
164
|
+
api-docs/
|
|
165
|
+
├── index.html
|
|
166
|
+
└── openapi.yaml
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Use custom progressive-enhancement assets with `--css` and `--js`. The default stylesheet exposes `--font-sans` and
|
|
170
|
+
`--font-mono` on `:root`; change those two variables to override the embedded font pair. Use `--check` to avoid writing
|
|
171
|
+
and return exit code `1` when generated files are missing or stale. Input and validation errors return exit code `2`.
|
|
172
|
+
|
|
173
|
+
Nadoc can also be used from Python:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from nadoc import render
|
|
177
|
+
|
|
178
|
+
result = render(
|
|
179
|
+
"openapi.yaml",
|
|
180
|
+
overlay="documentation-overlay.yaml",
|
|
181
|
+
config="nadoc.yaml",
|
|
182
|
+
output_dir="api-docs",
|
|
183
|
+
)
|
|
184
|
+
print(result.html_path)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Supported scope
|
|
188
|
+
|
|
189
|
+
Nadoc's versioned renderer profile is `nadoc-oas31-profile-v1`. It supports conventional path operations and top-level
|
|
190
|
+
webhook operations, parameters, request and response bodies, examples, servers and variables, tags, security schemes
|
|
191
|
+
and requirements, response headers and links, `x-codeSamples`, and a substantial documentation-focused subset of JSON
|
|
192
|
+
Schema 2020-12. Local references are consumed for schemas, parameters, request bodies, responses, headers, examples,
|
|
193
|
+
links, and root path items. Callback names are rendered as metadata; callback expressions and nested callback
|
|
194
|
+
operations are not expanded.
|
|
195
|
+
|
|
196
|
+
Schema composition and conditionals are presented as distinct branches rather than flattened. Nadoc also renders
|
|
197
|
+
common constraints and annotations and generates bounded, deterministic example values. These are documentation
|
|
198
|
+
features: Nadoc does not evaluate schema validity or claim that generated examples satisfy every constraint.
|
|
199
|
+
|
|
200
|
+
External file and network references, discriminator behavior, dynamic reference scope, callback operation expansion,
|
|
201
|
+
request execution, and formal validation remain outside the profile. Nadoc never fetches references or external
|
|
202
|
+
examples. Emitting a merged YAML document preserves input data but does not imply that every field has an HTML
|
|
203
|
+
representation. See the
|
|
204
|
+
[compatibility reference](https://github.com/ibudidi/nadoc/blob/main/COMPATIBILITY.md) for the detailed supported
|
|
205
|
+
profile and explicit boundaries.
|
|
206
|
+
|
|
207
|
+
Nadoc natively targets OpenAPI 3.1 and accepts semantic versions in the `3.1.x` series. OpenAPI `3.0.x` documents are
|
|
208
|
+
rendered through a compatibility profile and produce one `OAS30_COMPAT` warning. The compatibility layer interprets
|
|
209
|
+
3.0 Schema Object `nullable` and boolean exclusive-bound semantics for documentation without changing the emitted
|
|
210
|
+
document. Nadoc rejects prerelease versions and versions outside the 3.0 and 3.1 series. `paths` may be omitted, but must be an object
|
|
211
|
+
when present. Nadoc's compatibility diagnostics are separate from formal OpenAPI
|
|
212
|
+
validation; the current release does not claim to validate every OpenAPI or JSON Schema constraint. In non-strict mode,
|
|
213
|
+
`render()` returns semantic-omission diagnostics in `RenderResult.diagnostics`; strict mode promotes them to errors.
|
|
214
|
+
The CLI prints non-strict diagnostics as `severity: CODE at location: message`. Compatibility/input failures exit `2`,
|
|
215
|
+
stale `--check` output exits `1`, and successful rendering exits `0`. For formal validation in CI, run a dedicated
|
|
216
|
+
OpenAPI 3.1 validator before Nadoc; Nadoc intentionally does not bundle or prescribe one.
|
|
217
|
+
|
|
218
|
+
## Generated site behavior
|
|
219
|
+
|
|
220
|
+
Generated pages include embedded styling, syntax-highlighted examples, theme selection, sidebar search, keyboard-aware
|
|
221
|
+
tabs, copy controls, server selection, language preference, mobile navigation, and a no-JavaScript documentation
|
|
222
|
+
baseline. Nadoc escapes document values and renders Markdown with raw HTML disabled. Generated pages embed Inter,
|
|
223
|
+
JetBrains Mono, CSS, JavaScript, and language icons, so they do not load resources from the network.
|
|
224
|
+
|
|
225
|
+
OpenAPI-provided links are clickable only when they are absolute HTTP or HTTPS URLs. Custom files passed with `--css`
|
|
226
|
+
or `--js` are trusted inputs and are embedded verbatim; do not use custom assets from an untrusted source. See the
|
|
227
|
+
[security policy](SECURITY.md) for vulnerability reporting and the complete input trust model.
|
|
228
|
+
|
|
229
|
+
## Contributing
|
|
230
|
+
|
|
231
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, utility commands, testing,
|
|
232
|
+
and pull-request requirements. Compatibility changes must also update
|
|
233
|
+
[COMPATIBILITY.md](https://github.com/ibudidi/nadoc/blob/main/COMPATIBILITY.md). Report defects or request features in the
|
|
234
|
+
[issue tracker](https://github.com/ibudidi/nadoc/issues).
|
|
235
|
+
|
|
236
|
+
Release changes are recorded in [CHANGELOG.md](CHANGELOG.md).
|
|
237
|
+
|
|
238
|
+
Nadoc is available under the [MIT License](LICENSE).
|
nadoc-0.1.0/README.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Nadoc
|
|
2
|
+
|
|
3
|
+
Deterministic static documentation for OpenAPI.
|
|
4
|
+
|
|
5
|
+
Nadoc converts an OpenAPI 3.1 document and an optional OpenAPI Overlay 1.x document into a self-contained,
|
|
6
|
+
server-rendered API documentation site. CSS, JavaScript, and language icons are embedded in the generated HTML;
|
|
7
|
+
Python is only required at generation time.
|
|
8
|
+
|
|
9
|
+
> Nadoc's renderer profile is tested and explicitly documented. Strict mode rejects known unsupported semantics rather
|
|
10
|
+
> than silently omitting them.
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- Python 3.10 or newer
|
|
15
|
+
- An OpenAPI 3.0 or 3.1 YAML or JSON document
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
For an isolated command-line installation from PyPI:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pipx install nadoc
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Alternatively, install Nadoc into the active Python environment:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python3 -m pip install nadoc
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
From this source checkout:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python3 -m pip install .
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick start
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
nadoc openapi.yaml --output-dir api-docs
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Open `api-docs/index.html` in a browser. The generated HTML embeds Nadoc's CSS, JavaScript, language icons, and Latin
|
|
44
|
+
subsets of Inter and JetBrains Mono, so viewing it does not require network resources. Run `nadoc --help` for all command-line options.
|
|
45
|
+
|
|
46
|
+
## Configuration
|
|
47
|
+
|
|
48
|
+
Apply an optional overlay:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
nadoc openapi.yaml \
|
|
52
|
+
--overlay documentation-overlay.yaml \
|
|
53
|
+
--output-dir api-docs
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The HTML shell is minified by default; pass `--no-minify` (or `output.minify: false`) to keep the indented layout.
|
|
57
|
+
Embedded code and assets are never altered by minification. To keep the single file small, Nadoc ships Latin-subset
|
|
58
|
+
fonts, draws repeated icons from CSS masks instead of inline SVG, and compacts syntax-highlighted samples.
|
|
59
|
+
|
|
60
|
+
Customize the generated theme with a versioned Nadoc configuration:
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
# nadoc.yaml
|
|
64
|
+
version: 1
|
|
65
|
+
input:
|
|
66
|
+
spec: ./openapi.yaml
|
|
67
|
+
overlay: ./overlay.yaml
|
|
68
|
+
strict: true
|
|
69
|
+
site:
|
|
70
|
+
title: Acme API
|
|
71
|
+
product_name: Developer Platform
|
|
72
|
+
language: en
|
|
73
|
+
theme:
|
|
74
|
+
default: system
|
|
75
|
+
preset: night-owl
|
|
76
|
+
colors:
|
|
77
|
+
primary: "#2563eb"
|
|
78
|
+
code_samples:
|
|
79
|
+
languages: [curl, python, javascript]
|
|
80
|
+
output:
|
|
81
|
+
directory: ./api-docs
|
|
82
|
+
html_file: index.html
|
|
83
|
+
spec_file: openapi.yaml
|
|
84
|
+
emit_spec: true
|
|
85
|
+
minify: true
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
nadoc --config nadoc.yaml
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Config version 1 supports `input.spec`, `input.overlay`, `input.strict`, `site.title`, `site.product_name`,
|
|
93
|
+
`site.language`, `theme.default`, `theme.preset`, `theme.colors.primary`, `code_samples.languages`, `output.directory`,
|
|
94
|
+
`output.html_file`, `output.spec_file`, `output.emit_spec`, and `output.minify`. Relative input and output paths are resolved from the directory containing
|
|
95
|
+
the config file, so `nadoc --config nadoc.yaml` is independent of the current working directory.
|
|
96
|
+
|
|
97
|
+
`code_samples.languages` controls which request examples Nadoc generates and their order after authored `x-codeSamples`. Supported values are
|
|
98
|
+
`curl`, `python`, `javascript`, `node`, `go`, `java`, `php`, and `csharp`. All are generated by default for backward
|
|
99
|
+
compatibility. Use an empty list (`languages: []`) to disable generated examples; authored OpenAPI `x-codeSamples`
|
|
100
|
+
remain available.
|
|
101
|
+
|
|
102
|
+
The default display mode may be `system`, `light`, or `dark`. Presets include the dark themes `atom-one-dark`,
|
|
103
|
+
`dracula`, `night-owl`, `catppuccin-dark`, and `ayu-dark`, plus the light themes `atom-one-light`,
|
|
104
|
+
`bracket-light-pro`, `bluloco-light`, `catppuccin-light`, and `ayu-light`. The Atom One, Catppuccin, and Ayu presets are paired:
|
|
105
|
+
either variant styles both display modes, while the preset name selects the initial mode. When
|
|
106
|
+
`theme.default` is omitted, a preset selects its native light or dark mode. The theme toggle remains available and
|
|
107
|
+
uses Nadoc's neutral palette for the opposite mode except when a paired Atom One, Catppuccin, or Ayu preset is selected.
|
|
108
|
+
|
|
109
|
+
The primary color must use `#RRGGBB` notation. It overrides a preset's primary and accent colors and Nadoc derives
|
|
110
|
+
appropriate light and dark brand shades from it. Elevation shadows are always neutral grey/black and never inherit
|
|
111
|
+
the primary color, so unusual or red brand colors do not tint cards and panels.
|
|
112
|
+
The header brand mark uses the first non-whitespace character of the configured title, falling back to the OpenAPI
|
|
113
|
+
`info.title`.
|
|
114
|
+
|
|
115
|
+
Explicit command-line or Python API values override config values, which override Nadoc defaults. Boolean CLI
|
|
116
|
+
options support both forms, such as `--minify`/`--no-minify`, `--strict`/`--no-strict`, and
|
|
117
|
+
`--emit-spec`/`--no-emit-spec`. Output file settings accept file names only; place them using `output.directory`.
|
|
118
|
+
Other sections from the proposed v1 schema are reserved for future releases and are rejected rather than silently
|
|
119
|
+
ignored.
|
|
120
|
+
|
|
121
|
+
Generated files:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
api-docs/
|
|
125
|
+
├── index.html
|
|
126
|
+
└── openapi.yaml
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Use custom progressive-enhancement assets with `--css` and `--js`. The default stylesheet exposes `--font-sans` and
|
|
130
|
+
`--font-mono` on `:root`; change those two variables to override the embedded font pair. Use `--check` to avoid writing
|
|
131
|
+
and return exit code `1` when generated files are missing or stale. Input and validation errors return exit code `2`.
|
|
132
|
+
|
|
133
|
+
Nadoc can also be used from Python:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from nadoc import render
|
|
137
|
+
|
|
138
|
+
result = render(
|
|
139
|
+
"openapi.yaml",
|
|
140
|
+
overlay="documentation-overlay.yaml",
|
|
141
|
+
config="nadoc.yaml",
|
|
142
|
+
output_dir="api-docs",
|
|
143
|
+
)
|
|
144
|
+
print(result.html_path)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Supported scope
|
|
148
|
+
|
|
149
|
+
Nadoc's versioned renderer profile is `nadoc-oas31-profile-v1`. It supports conventional path operations and top-level
|
|
150
|
+
webhook operations, parameters, request and response bodies, examples, servers and variables, tags, security schemes
|
|
151
|
+
and requirements, response headers and links, `x-codeSamples`, and a substantial documentation-focused subset of JSON
|
|
152
|
+
Schema 2020-12. Local references are consumed for schemas, parameters, request bodies, responses, headers, examples,
|
|
153
|
+
links, and root path items. Callback names are rendered as metadata; callback expressions and nested callback
|
|
154
|
+
operations are not expanded.
|
|
155
|
+
|
|
156
|
+
Schema composition and conditionals are presented as distinct branches rather than flattened. Nadoc also renders
|
|
157
|
+
common constraints and annotations and generates bounded, deterministic example values. These are documentation
|
|
158
|
+
features: Nadoc does not evaluate schema validity or claim that generated examples satisfy every constraint.
|
|
159
|
+
|
|
160
|
+
External file and network references, discriminator behavior, dynamic reference scope, callback operation expansion,
|
|
161
|
+
request execution, and formal validation remain outside the profile. Nadoc never fetches references or external
|
|
162
|
+
examples. Emitting a merged YAML document preserves input data but does not imply that every field has an HTML
|
|
163
|
+
representation. See the
|
|
164
|
+
[compatibility reference](https://github.com/ibudidi/nadoc/blob/main/COMPATIBILITY.md) for the detailed supported
|
|
165
|
+
profile and explicit boundaries.
|
|
166
|
+
|
|
167
|
+
Nadoc natively targets OpenAPI 3.1 and accepts semantic versions in the `3.1.x` series. OpenAPI `3.0.x` documents are
|
|
168
|
+
rendered through a compatibility profile and produce one `OAS30_COMPAT` warning. The compatibility layer interprets
|
|
169
|
+
3.0 Schema Object `nullable` and boolean exclusive-bound semantics for documentation without changing the emitted
|
|
170
|
+
document. Nadoc rejects prerelease versions and versions outside the 3.0 and 3.1 series. `paths` may be omitted, but must be an object
|
|
171
|
+
when present. Nadoc's compatibility diagnostics are separate from formal OpenAPI
|
|
172
|
+
validation; the current release does not claim to validate every OpenAPI or JSON Schema constraint. In non-strict mode,
|
|
173
|
+
`render()` returns semantic-omission diagnostics in `RenderResult.diagnostics`; strict mode promotes them to errors.
|
|
174
|
+
The CLI prints non-strict diagnostics as `severity: CODE at location: message`. Compatibility/input failures exit `2`,
|
|
175
|
+
stale `--check` output exits `1`, and successful rendering exits `0`. For formal validation in CI, run a dedicated
|
|
176
|
+
OpenAPI 3.1 validator before Nadoc; Nadoc intentionally does not bundle or prescribe one.
|
|
177
|
+
|
|
178
|
+
## Generated site behavior
|
|
179
|
+
|
|
180
|
+
Generated pages include embedded styling, syntax-highlighted examples, theme selection, sidebar search, keyboard-aware
|
|
181
|
+
tabs, copy controls, server selection, language preference, mobile navigation, and a no-JavaScript documentation
|
|
182
|
+
baseline. Nadoc escapes document values and renders Markdown with raw HTML disabled. Generated pages embed Inter,
|
|
183
|
+
JetBrains Mono, CSS, JavaScript, and language icons, so they do not load resources from the network.
|
|
184
|
+
|
|
185
|
+
OpenAPI-provided links are clickable only when they are absolute HTTP or HTTPS URLs. Custom files passed with `--css`
|
|
186
|
+
or `--js` are trusted inputs and are embedded verbatim; do not use custom assets from an untrusted source. See the
|
|
187
|
+
[security policy](SECURITY.md) for vulnerability reporting and the complete input trust model.
|
|
188
|
+
|
|
189
|
+
## Contributing
|
|
190
|
+
|
|
191
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, utility commands, testing,
|
|
192
|
+
and pull-request requirements. Compatibility changes must also update
|
|
193
|
+
[COMPATIBILITY.md](https://github.com/ibudidi/nadoc/blob/main/COMPATIBILITY.md). Report defects or request features in the
|
|
194
|
+
[issue tracker](https://github.com/ibudidi/nadoc/issues).
|
|
195
|
+
|
|
196
|
+
Release changes are recorded in [CHANGELOG.md](CHANGELOG.md).
|
|
197
|
+
|
|
198
|
+
Nadoc is available under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=83"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "nadoc"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "A simple static documentation generator for OpenAPI 3.1 specs"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Ibudidi", email = "ibudidi@users.noreply.github.com" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["openapi", "documentation", "static-site", "api"]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"Jinja2>=3.1,<4",
|
|
18
|
+
"markdown-it-py>=3,<5",
|
|
19
|
+
"Pygments>=2.19,<3",
|
|
20
|
+
"PyYAML>=6,<7",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 4 - Beta",
|
|
25
|
+
"Environment :: Console",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Operating System :: OS Independent",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3.10",
|
|
30
|
+
"Programming Language :: Python :: 3.11",
|
|
31
|
+
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Topic :: Documentation",
|
|
34
|
+
"Topic :: Software Development :: Documentation",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = [
|
|
39
|
+
"build>=1,<2",
|
|
40
|
+
"pip-audit>=2.7,<3",
|
|
41
|
+
"pyright>=1.1,<2",
|
|
42
|
+
"ruff>=0.9,<1",
|
|
43
|
+
"setuptools>=83",
|
|
44
|
+
"twine>=6,<7",
|
|
45
|
+
]
|
|
46
|
+
fonts = [
|
|
47
|
+
"fonttools[woff]>=4.53,<5",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.urls]
|
|
51
|
+
Homepage = "https://github.com/ibudidi/nadoc"
|
|
52
|
+
Repository = "https://github.com/ibudidi/nadoc"
|
|
53
|
+
Issues = "https://github.com/ibudidi/nadoc/issues"
|
|
54
|
+
Changelog = "https://github.com/ibudidi/nadoc/blob/main/CHANGELOG.md"
|
|
55
|
+
|
|
56
|
+
[project.scripts]
|
|
57
|
+
nadoc = "nadoc.cli:main"
|
|
58
|
+
|
|
59
|
+
[tool.setuptools.packages.find]
|
|
60
|
+
where = ["src"]
|
|
61
|
+
|
|
62
|
+
[tool.setuptools.package-data]
|
|
63
|
+
nadoc = [
|
|
64
|
+
"templates/*.j2",
|
|
65
|
+
"assets/*.css",
|
|
66
|
+
"assets/*.js",
|
|
67
|
+
"assets/icons/*.svg",
|
|
68
|
+
"assets/fonts/*.woff2",
|
|
69
|
+
"assets/fonts/*.txt",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[tool.setuptools.dynamic]
|
|
73
|
+
version = { attr = "nadoc.__version__" }
|
|
74
|
+
|
|
75
|
+
[tool.pyright]
|
|
76
|
+
include = ["src", "tests", "scripts"]
|
|
77
|
+
pythonVersion = "3.10"
|
|
78
|
+
|
|
79
|
+
[tool.ruff]
|
|
80
|
+
line-length = 120
|
|
81
|
+
target-version = "py310"
|
|
82
|
+
src = ["src", "tests"]
|
|
83
|
+
|
|
84
|
+
[tool.ruff.lint]
|
|
85
|
+
select = [
|
|
86
|
+
"E", # pycodestyle errors
|
|
87
|
+
"W", # pycodestyle warnings
|
|
88
|
+
"F", # pyflakes
|
|
89
|
+
"I", # isort
|
|
90
|
+
"UP", # pyupgrade
|
|
91
|
+
"B", # flake8-bugbear
|
|
92
|
+
"C4", # flake8-comprehensions
|
|
93
|
+
"SIM", # flake8-simplify
|
|
94
|
+
"RUF", # ruff-specific rules
|
|
95
|
+
"PLW", # pylint warnings
|
|
96
|
+
]
|
|
97
|
+
ignore = [
|
|
98
|
+
"RUF001", # ambiguous unicode: the renderer deliberately emits typographic symbols such as ≥ and —
|
|
99
|
+
"RUF002",
|
|
100
|
+
"RUF003",
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
[tool.ruff.lint.per-file-ignores]
|
|
104
|
+
# Tests assert on long literal CSS/JS fragments that cannot be wrapped meaningfully.
|
|
105
|
+
"tests/*" = ["E501"]
|
nadoc-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Deterministic static documentation for OpenAPI."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
from .api import RenderResult, render
|
|
6
|
+
from .diagnostics import Diagnostic
|
|
7
|
+
from .errors import RendererError
|
|
8
|
+
|
|
9
|
+
__all__ = ["Diagnostic", "RenderResult", "RendererError", "render"]
|