OpenAPI spec: upstream source and known issues
The files under openapi/ (except generator-config.yaml and .gitkeep) are downloaded from Thingiverse via scripts/fetch_openapi_spec.py. We do not manually edit those downloaded files, because any changes would be overwritten the next time the spec is re-fetched.
Upstream spec issues
The Thingiverse OpenAPI spec has compliance issues that strict OpenAPI 3.0 consumers (including openapi-python-client) do not accept:
- Missing
descriptionon response objects — In OpenAPI 3.0, every Response Object must have adescriptionfield. Several endpoints define a200response withcontentbut nodescription, which causes the generator to fail.
Other upstream issues (arrays without items, path parameters optional or not matching the path, etc.) are fixed automatically by the patch script (see below).
Our approach: patch the bundled spec with a script
We keep the downloaded source spec untouched. After Redocly produces a single bundled file (openapi/bundled.yaml), we run scripts/patch_bundled_spec_full.py, which applies all fixes so the generator can build the SDK. The pipeline is:
- Fetch —
scripts/fetch_openapi_spec.py→ pristine files from Thingiverse. - Bundle — Redocly →
openapi/bundled.yaml. - Patch —
scripts/patch_bundled_spec_full.py→ fix bundled spec in place. - Generate — openapi-python-client →
thingiverse/.
The script adds missing response descriptions, adds items to array schemas, sets path parameters to required: true, fixes path templating, and moves parameters that are in path but not in the path template to query. If the generator reports new issues after a fetch, extend the script and re-run.
Updating the fix script
When the upstream spec changes and new generator errors appear, edit scripts/patch_bundled_spec_full.py to add or adjust fixes. Run ./scripts/generate_client.sh to verify. The following steps are only needed if you want to recreate a diff-based patch (optional):
- Fetch the API spec freshly from Thingiverse
- Bundle it (merge into a single file)
- Create a copy of that merged file
- Try to generate the SDK
openapi-python-client generate --path openapi/bundled.yaml --config openapi/generator-config.yaml --output-path thingiverse --overwrite
-
Manually address all the issues that are reported Edit
openapi/bundled.yaml(e.g. add missingdescriptionunder responses, fix schema issues). You can usescripts/add_response_descriptions_in_place.py openapi/bundled.yamlto insert missing response descriptions without reordering the file. -
Repeat from step 4 until the generator runs without errors (warnings about omitted endpoints/schemas are acceptable if you can’t fix them).
-
Diff the copy from step 3 with the fixed version
Then edit the first two lines of openapi/bundled.patch so both paths are openapi/bundled.yaml (the patch must apply to the file that will be produced by the bundle step):
- Change --- openapi/bundled.orig.yaml ... to --- openapi/bundled.yaml
- Change +++ openapi/bundled.yaml ... to +++ openapi/bundled.yaml
- Commit the updated patch (and remove
openapi/bundled.orig.yamlfrom the repo if it was added; it’s only for creating the diff).
The update script (i.e. the flow used in normal development) is: fetch → bundle → run patch_bundled_spec_full.py → generate. See scripts/generate_client.sh and the “Updating the API spec” section in the README.
Alternatives considered
- Manually editing downloaded files — Rejected: changes are lost on next fetch.
- Forking the spec in our repo — Rejected: we’d have to merge upstream changes by hand.
- A single diff patch file — Replaced by a script so we can fix many structural issues without a huge, fragile patch.
- Reporting upstream — Still recommended (e.g. open an issue or PR with Thingiverse) so the official spec becomes compliant; the patch can be simplified or removed once upstream is fixed.