feat(models): update Python SDK schemas for UCP release 2026-08-25 - #87
Merged
damaz91 merged 2 commits intoAug 27, 2026
Merged
Conversation
|
Hi @segiodongo, Thanks for submitting this PR! Looks like it's failing backward compatibility when regenerating models for 2026-04-08 and Lint - though I see in your description that you ran Lint check (potentially not across all updated files ?). Could you please take a look at these 2 issues. Thanks! |
segiodongo
force-pushed
the
feat/v825-upgrade
branch
from
August 25, 2026 18:23
0a5d127 to
e414d4b
Compare
segiodongo
force-pushed
the
feat/v825-upgrade
branch
5 times, most recently
from
August 26, 2026 17:13
056e4e8 to
99e5979
Compare
- Update schema preprocessing pipeline for v2026-08-25 response definitions - Regenerate Pydantic models from UCP release/2026-08-25 JSON schemas - Restructure models into common, shopping, and transport verticals - Add Location Search/Lookup, Loyalty, Request Constraints, Permalinks, and Actions models - Move shared primitives and payment extensions to common namespace - Bump package version to 0.5.0 in pyproject.toml and update README.md
damaz91
force-pushed
the
feat/v825-upgrade
branch
from
August 27, 2026 14:09
99e5979 to
bdfb3f6
Compare
damaz91
approved these changes
Aug 27, 2026
This was referenced Aug 28, 2026
bug: profile.json JWK conditional rules and unit.json C62 scale pin are dropped by the generator
#88
Closed
carolinerg1
pushed a commit
that referenced
this pull request
Sep 1, 2026
* test: fix stale shopping.types import paths in the codegen pipeline suite The HAVE_SDK import gate at the top of test_codegen_pipeline.py still imported Description/Totals from ucp_sdk.models.schemas.shopping.types, paths that moved to ucp_sdk.models.schemas.common.types when #87 (the 2026-08-25 UCP release regen) restructured the schema tree. The stale paths raise ModuleNotFoundError, which the surrounding try/except catches and sets HAVE_SDK = False, so every test gated on HAVE_SDK skips instead of running (unittest reports a skip as OK, so the suite reads green while ~37% of it never executes). Fix every stale shopping.types.* reference in the file: description, totals (+ its request variants), signals (+ its request variants), and error_response moved to common.types under the same class names, so those tests now run and pass unmodified. Two targets did not survive the schema restructuring at all -- card_payment_instrument.Constraints (a uniqueItems brands field) and merchant_fulfillment_config's nested additionalProperties:false object (now business_fulfillment_config, reshaped) -- so their four tests become documented unittest.skip with the reason recorded in the schema, not silently deleted. Before: 89 tests, 33 skipped (26 on the HAVE_SDK gate, 7 on 'executing the module needs pydantic', which also reads HAVE_SDK). After: 89 tests, 4 skipped, all four with a stated schema-shape reason. No production code changes; test-only. * test: add failing coverage for JWK conditional rules and unit scale pin profile.json's jwk_public_key def carries five if/then rules (two conditional-required: an EC key needs crv/x/y, an OKP key needs crv/x; three conditional const-pins matching curve to algorithm: P-256/ES256, P-384/ES384, Ed25519/EdDSA), and unit.json pins scale to 0 when unit is C62. All six are dropped by the current generator, so the committed JwkPublicKey and Unit models validate payloads the spec rejects. Two independent scanner bugs cause this, isolated here at both the injector level (schema-scan unit tests against synthetic fixtures) and the semantic level (against the real committed models): (a) find_conditional_required only looks at a branch's own properties; an allOf branch carrying just {if, then} with no properties of its own (every JWK rule) is invisible, with no warning. find_conditional_bounds already threads the enclosing object's properties into such branches; find_conditional_required never picked up that fix. (b) find_conditional_bounds only recognizes the four numeric bound keywords (minimum/maximum/exclusiveMinimum/exclusiveMaximum) in a then.properties.<field> constraint. unit.json's scale pin and all three JWK algorithm pins use const, which is rejected as an unsupported shape and dropped (with a warning, unlike (a)). (c) Shared: in both scanners, a rule's own documentation title (JWK gives each branch a human-readable title, e.g. "EC keys carry crv, x, y") overwrites current_class_name via the same code path used for real class-defining titles, misattributing the rule to a nonexistent class instead of JwkPublicKey. Kill-rate note: test_schema_scan_skips_else_branches and test_schema_scan_skips_rules_whose_fields_were_stripped (both pre-existing) stay green, confirming the new scope-threading and const-recognition do not loosen the existing else-branch and stripped-field guards. RED: 109 tests, 9 failures + 1 error, 4 documented skips (unchanged from the prior commit). Generator fix and regen follow in separate commits per repo convention. * fix(codegen): thread conditional-rule scope and recognize const pins Three bugs in the postprocessing scanners were dropping all five of profile.json's jwk_public_key if/then rules and unit.json's C62 scale pin, letting the generated JwkPublicKey and Unit models validate payloads the spec rejects: (a) find_conditional_required only looked at a branch's own properties. An allOf branch carrying just {if, then} with no properties of its own (every JWK rule is exactly this shape) was invisible, silently, with no warning. find_conditional_bounds already threads the enclosing object's properties into such branches via an enclosing_properties parameter; find_conditional_required now does the same. (b) find_conditional_bounds only recognized the four numeric bound keywords (minimum/maximum/exclusiveMinimum/exclusiveMaximum) in a then.properties.<field> constraint, so a bare {"const": ...} constraint fell outside _BOUND_KEYWORDS and the whole rule returned None (unit.json's scale pin, and all three JWK curve/algorithm pairings, are const-shaped). _BOUND_KEYWORDS gains a "const" entry mapped to not-equal, reusing the existing "value <op> limit -> violation" template unchanged; the describe() type check is split so const may be a string (JWK's algorithm names) while the numeric keywords keep their existing int/float requirement. (c) Shared by both scanners: a rule's own documentation title (JWK gives each branch a human-readable one, e.g. "EC keys carry crv, x, y") was adopted as current_class_name via the same code path used for real class-defining titles, misattributing the rule to a nonexistent class instead of the enclosing JwkPublicKey. A new _is_bare_conditional_branch() helper recognizes an if/then node with no properties of its own as rule documentation, not a type, and both scanners now skip title adoption for it. Fixed at the generator level only (postprocess_models.py); no generated model files touched in this commit. Regeneration against the pinned 2026-08-25 UCP schema follows in a separate commit, which is what turns the six still-red semantic tests green (the four injector-level unit tests added in the prior commit -- which exercise the scanners directly against synthetic fixtures, not the committed models -- already pass). 109 tests, 6 failures (JwkConditionalRulesSemanticTest x5, UnitScaleSemanticTest x1), 4 documented skips. * chore(models): regenerate against the pinned 2026-08-25 UCP schema Regenerates via ./generate_models.sh 2026-08-25 (the same command the model-drift CI job runs) to pick up the postprocessing fix in the prior commit. Six files change: - profile.py: JwkPublicKey gains both a conditional-required validator (EC needs crv/x/y, OKP needs crv/x) and a conditional-bounds validator (P-256/ES256, P-384/ES384, Ed25519/EdDSA pairing). - common/types/unit.py (+ its create/update request variants): Unit gains a conditional-bounds validator pinning scale to 0 when unit is C62. - common/types/total.py, common/types/totals.py: unchanged behavior, picked up only because the conditional-bounds checks dict (embedded verbatim in every class using this validator family) now also carries the const entry. Verified: - Full suite: 109 tests, 0 failures, 4 documented skips (all six new tests from the RED commit now pass). - Double-regen: ran generate_models.sh 2026-08-25 twice; diff -rq between both outputs (excluding __pycache__) is empty. - Kill-test: reverted postprocess_models.py to its pre-fix state, regenerated, reinstalled -- the same 9 failures + 1 error from the RED commit reappeared verbatim. Restored the fix and regenerated again to confirm the suite returns to green. - pre-commit run on the changed files: clean (ruff, ruff-format, codespell, trailing-whitespace, end-of-file-fixer all pass). Not committed: README.md, which ruff format also reformats (a pre-existing docstring-code-block spacing drift in main, unrelated to this fix -- the model-drift CI job only diffs src/ucp_sdk/models/schemas, so this was never caught there). Left untouched to keep this diff scoped to the constraint fix. --------- Co-authored-by: Vishal Katyal <vishal@katyal.ai>
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.
Description
This PR updates the Python SDK to be fully compatible with the UCP 2026-08-25 specification release.
Key Changes
Schema Preprocessing & Codegen Pipeline:
preprocess_schemas.pyforallOf,anyOf, andoneOfmerging.normalize_metadata_schemasto dynamically detect and include all UCP metadata response envelopes (includingresponse_catalog_schemaandresponse_location_schema).per-file-ignoresinpyproject.tomlfor generated schemas, preprocessing/postprocessing scripts, and test suites.Model Regeneration & Reorganization:
./generate_models.sh 2026-08-25.ucp_sdk.models.schemas.common): Added models for Location Search & Lookup (location_search.py,location_lookup.py), Loyalty, Payment Terms, AP2 Mandates, Split Payments, and Request Constraints.ucp_sdk.models.schemas.common.types): Relocated shared types (amounts, prices, totals, postal address, signals, error/warning messages, pagination, time interval, unit price) from shopping into the common namespace.ucp_sdk.models.schemas.shopping): Updated Cart, Checkout, Order, Catalog Search/Lookup, Buyer Consent, and Permalinks to reference the reorganized common types and new fulfillment destinations.ucp_sdk.models.schemas.transports): Generated transport bindings for REST, MCP tool calls, JSON-RPC, and embedded/A2A messaging.ucp_sdk.models.schemas): Addedprofile.pyand updated capability/service definitions.Documentation & Versioning:
0.5.0inpyproject.tomlandsrc/ucp_sdk/__init__.py.README.mdpackage reference table and codegen instructions..gitignoreto ignore temporary codegen artifacts (ucp/,uv.lock).Verification
uv run ruff formatanduv run ruff checkpassed cleanly (0 errors).uv run python -m unittest discover tests/passed (88 tests passed, 0 failures).