Skip to content

Regenerate against the gateway 0.7.0 spec - #25

Merged
bburda merged 1 commit into
mainfrom
release/spec-0.7.0
Sep 2, 2026
Merged

bburda merged 1 commit into
mainfrom
release/spec-0.7.0

Conversation

@bburda

@bburda bburda commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Pull Request

Summary

Moves the spec snapshot from gateway 0.6.0 to 0.7.0 and makes both clients follow it.

The spec. Exported from a gateway built at the released 0.7.0 tag. It grows from 151 paths and 233 operations to 155 and 238: a fault trigger collection on apps with three operations, and two docs routes. No path was removed, so the TypeScript client needed no source change.

Lifecycle. Twelve operation ids lost their plural form. getAppsStatus is now getAppStatus, and the four transitions follow, on apps and components. The generated modules are renamed with them, so the re-export named modules that no longer exist and importing that group raised ImportError.

Endpoints with no way through. Three generated endpoints were reachable in the generated tree and nowhere in the package: the two capability description endpoints 0.7.0 adds to the server group, and get_app_area, which predates this release. A new group is noticed because its file is missing; an operation added to an existing group was not, so a test now compares each generated group against what its re-export lists.

Fault triggers. New group, so it gets a re-export like the others. It sits apart from the existing triggers API: a trigger there watches a resource on any entity type, while these fire on the faults of one app and the gateway exposes them on apps only.

The auth import. /auth/authorize and /auth/token now accept application/x-www-form-urlencoded beside application/json, which RFC 6749 requires of a token endpoint. openapi-python-client types a body that has one schema under two content types as Schema | Unset = UNSET, but the import line it writes brings in only the UNSET sentinel, not the Unset class the annotation names:

from ...types import UNSET, Response
...
body: AuthCredentials | AuthCredentials | Unset = UNSET,

Importing either module raises NameError, which takes the whole authentication group with it. 0.29.1 is the newest release and emits the same thing; its content_type_overrides setting collapses the duplicated union member but does not add the import. generate.sh now adds the missing name after generation, looking for the shape rather than for those two files by name.

How many modules it repairs depends on where it runs. openapi-python-client runs its own formatting hooks after generation, and pipx run gives it an environment where ruff is not on PATH - the CI log says so. Without those hooks the import line is left short in far more places, so CI repairs 81 modules while a local run that has ruff available repairs the two auth ones. The generated code is the same either way once the step has run.

The exporting gateway's port. servers carried whichever port the gateway that produced the export was bound to. That is a property of one run, not of the API, and it reaches everyone who reads the committed spec. export-spec.sh now pins it to the documented default and says when it changed something. Nothing depends on the value - neither generated client reads servers, both take the base URL from their caller - so the host stays as the gateway reports it and only the port is pinned.

Docs and versions. Both packages go to 0.7.0. The README named 0.5.0 as the gateway release the spec comes from, and told readers to pip install from a package index. No workflow publishes to one; the Python client ships as a wheel attached to a GitHub release, so the documented command could never work.


Issue


Type

  • Bug fix
  • New feature or tests
  • Breaking change
  • Documentation only

Testing

The gateway was built from the released 0.7.0 tag, whose tree is identical to the commit the spec was exported from, so the snapshot here is the released one.

Python client:

  • pytest passes 124 tests. 34 are new: every api group is imported and every name it re-exports is checked to be bound, and every generated group is compared against its re-export so an unreachable endpoint fails here. The suite did not touch ros2_medkit_client.api before, so both failure shapes this release had used to pass here and fail in a consumer instead. Reverting the lifecycle names fails with ImportError, undoing the Unset repair fails with NameError, and dropping one name from a re-export fails with the list of what is unreachable.
  • ruff check src/ tests/ and ruff format --check src/ tests/ are clean.
  • The wheel builds as ros2_medkit_client-0.7.0-py3-none-any.whl.

TypeScript client:

  • npm run build, npm test (54 tests), npm run lint and npm run typecheck are all clean.

Spec and scripts:

  • Spectral reports 0 errors and 11 warnings, down from 19 on the 0.6.0 snapshot.
  • shellcheck is clean on both scripts. Running export-spec.sh against a gateway deliberately bound to a spare port prints Normalized server URL port 9611 -> 8080 and writes the default.

Against a running 0.7.0 gateway, not a mock:

  • get_capability_description answers 200 and get_app_area answers 200 through the re-exports they were missing, and list_fault_triggers reaches the gateway and gets its own answer.
  • The wheel built here was installed into the MCP server on its own branch, and its suite passes 221 tests. On the 0.6.0 wheel that branch does not run at all.
  • A locally packed @selfpatch/ros2-medkit-client-ts@0.7.0 was installed into the web UI on its own branch: typecheck, lint and build are clean, 736 unit tests pass, and its Playwright suite passes 21 tests against the live gateway.

The publish jobs derive the tag from the package version, so this produces py-v0.7.0/ros2_medkit_client-0.7.0-py3-none-any.whl and @selfpatch/ros2-medkit-client-ts@0.7.0, which is what the two dependent PRs pin.


Checklist

  • Breaking changes are clearly described (and announced in docs / changelog if needed)
  • Tests were added or updated if needed
  • Docs were updated if behavior or public API changed

@bburda bburda self-assigned this Sep 1, 2026
The snapshot moves from gateway 0.6.0 to 0.7.0: 155 paths and 238
operations, up from 151 and 233. A fault trigger collection appears on
apps with three operations, two docs routes appear, and no path is
removed, so the TypeScript client needs no source change.

Twelve lifecycle operation ids lose their plural form - getAppsStatus is
getAppStatus, and the four transitions follow, on apps and components.
The generated modules are renamed with them, so the re-export named
modules that no longer exist and importing that group raised ImportError.

Three generated endpoints were reachable in the generated tree and
nowhere in the package: the two capability description endpoints 0.7.0
adds to the server group, and get_app_area, which predates this release.
A new group is noticed because its file is missing; an operation added to
an existing group was not, so a test now compares each generated group
against what its re-export lists, and another imports every group and
checks each name it exports is bound. The suite did not touch
ros2_medkit_client.api at all before, so both failure shapes this release
had used to pass here and surface in a consumer instead.

/auth/authorize and /auth/token now accept application/x-www-form-urlencoded
beside application/json, as RFC 6749 requires of a token endpoint.
openapi-python-client types a body carrying one schema under two content
types as `Schema | Unset = UNSET` while importing only the UNSET
sentinel, so both modules raise NameError on import and take the whole
authentication group with them. 0.29.1 emits the same thing and its
content_type_overrides setting does not add the import, so generate.sh
adds the missing name after generation, matching the shape rather than
those two files by name.

servers carried whichever port the exporting gateway was bound to, which
is a property of one run rather than of the API. export-spec.sh pins it
to the documented default, replacing only the port in the authority so an
IPv6 literal keeps its brackets and userinfo survives.

Both packages go to 0.7.0, including the TypeScript lockfile's own
version, which npm ci does not compare and which had drifted two releases
behind. The README named 0.5.0 as the gateway release the spec comes
from, and documented a pip install from a package index that nothing
publishes to - the Python client ships as a wheel on a GitHub release.
@bburda
bburda force-pushed the release/spec-0.7.0 branch from 70f7382 to 30865fa Compare September 1, 2026 15:18
@bburda
bburda requested a review from mfaferek93 September 1, 2026 15:42
@bburda
bburda merged commit 0245d2c into main Sep 2, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regenerate against the gateway 0.7.0 spec

2 participants