Repository navigation
Management API: typed clients generated from the OpenAPI specs - #2
Merged
Merged
Conversation
The four specs (environment, workspace, platform, account) come from cbox-id integration/wave-6. scripts/generate_management.py turns them into typed modules; --check fails when the output is stale and --fetch refreshes a spec from a running server. typing-extensions becomes a runtime dependency for NotRequired/TypedDict on 3.10; pyyaml is dev-only.
EnvironmentClient, WorkspaceClient, PlatformClient and AccountClient, generated from the vendored specs and named after the server's actions. A hand-written transport carries the credential checks, Idempotency-Key reuse across retries (Retry-After honoured), the approval loop with same-origin polling and a return-pending mode, Cbox-Environment for root tokens, DPoP proofs, paging, and CboxIdApiError / ManagementNetworkError. Mirrors id-js's management client. Includes the Audit Logs helpers (buffered logger, export poller, chain verifier byte-compatible with the server's canonical JSON).
Typed answers (ManagementKey with a nullable token on replay, LegacyLoginProbe, ManifestSync, SelfServiceSignup, VerificationResend), webhook signature_scheme and webhooks.signature_scheme.change, log stream options and health, the log_streams.test failure kind, and organizations.portal_links.list/revoke. More routes now declare 202 approval_required, so their methods take approval=.
verify_standard_webhook() checks webhook-id / webhook-timestamp / webhook-signature for endpoints on the standard_webhooks scheme, with a whsec_ secret or the endpoint's hex Cbox secret, and is tested against the specification's vector. README: install line names v0.9.0.
…al specs; first PyPI release
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
cbox_id.management: typed clients for Cbox ID's four management planes, generated from the server's OpenAPI documents (cbox-idintegration/wave-7). It is the Python twin of id-js's management client (feat/management-client) and matches its behaviour.What's in it
EnvironmentClient,WorkspaceClient,PlatformClient,AccountClient. Method names come fromx-action, e.g.env.apps.secrets.rotate(id, body)andenv.sso.saml_metadata.import_(...). Bodies, queries anddataareTypedDicts, and the 253 generated operations passmypy --strict.Specs are vendored from cbox-id
integration/wave-7inopenapi/. They include the typed answers (ManagementKeywith a nullable token on replay,LegacyLoginProbe,ManifestSync,SelfServiceSignup,VerificationResend), webhooksignature_schemeandwebhooks.signature_scheme.change, log streamoptionsand health, thelog_streams.testfailurekind, andorganizations.portal_links.list/revoke.python -m scripts.generate_managementregenerates the code,--checkfails when the generated code is stale, and--fetch plane=urlrefreshes a spec from a running server. A drift test fails when the generated code and the specs disagree, and a surface snapshot catches API changes caused by generator edits.Runtime behaviour, same as id-js:
access_tokencan be a string or a callableenvironment=sendsCbox-Environmentfor root tokensIdempotency-Key, and retries reuse it while honouringRetry-AfterreplayedreflectsIdempotent-Replayedon_approval_required, the client pollspoll_url(same origin only) and repeats withCbox-ApprovalApprovalDeniedError/ApprovalExpiredErrorapproval="return"returns aPendingApprovalResultwithresume()CboxIdApiErrortakesrequest_idfrom the body first, thenX-Request-IdManagementNetworkError…_alliterators for paged listsAudit Logs helpers:
AuditLogger(batches of up to 100, one idempotency key per batch, a failed batch stays queued with its key),export_audit_logs(), andverify_audit_chain()/verify_audit_log_chain().canonical_json()reproduces the server's PHP quirks and is checked against id-js's server-computed vector (tests/fixtures/audit_chain.json).verify_standard_webhook()sits besideverify_webhook(). It verifies endpoints on thestandard_webhooksscheme (webhook-id/webhook-timestamp/webhook-signature) with awhsec_secret or the endpoint's hex Cbox secret, and it is tested against the Standard Webhooks spec vector.README: the install line now names v0.9.0.
Decisions
approval: the default call is typedApiResponse[T], andapproval="return"is typedApiResponse[T] | PendingApprovalResult[T].typing-extensions>=4.7, needed forNotRequiredon 3.10.pyyamlandtypes-PyYAMLare dev-only.ruff formatand E501, so the drift test compares bytes. The management tests are added to mypy's file list so theassert_typechecks run.Gate (run locally on Python 3.14; CI covers 3.10–3.13):
ruff check .,ruff format --check .,mypy,pytestall pass (209 tests), andpython -m scripts.generate_management --checkis clean. No version bump.Note: the wave-7 specs still carry no
x-scope/x-dangeron 45 actions (35 environment, 10 workspace; examples:apps.list,apps.create,invitations.send,environments.create). Their scope still comes through from the description's "Requires scope" line, but theirdangerisNonein the operation tables.