Skip to content

Commit e652462

Browse files
xiaoxuanz-hubdamaz91
authored andcommitted
update
1 parent 2a9beb9 commit e652462

30 files changed

Lines changed: 807 additions & 85 deletions

preprocess_schemas.py

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -514,13 +514,12 @@ def _create_single_variant(
514514
variant, op, file_path, global_variant_requirements
515515
)
516516

517-
# Rewrite $refs in top-level oneOf/anyOf branches (e.g. fulfillment_destination
518-
# has no properties, only oneOf with external $refs that need variant rewriting).
519-
for poly_key in ["oneOf", "anyOf"]:
520-
if poly_key in variant:
521-
rewrite_refs_to_variants(
522-
variant[poly_key], op, file_path, global_variant_requirements
523-
)
517+
# Rewrite all external $refs in the variant schema to point to their
518+
# corresponding request variants where applicable. This covers top-level
519+
# oneOf/anyOf/allOf branches as well as array items.
520+
rewrite_refs_to_variants(
521+
variant, op, file_path, global_variant_requirements
522+
)
524523
return variant
525524

526525

@@ -577,19 +576,28 @@ def normalize_metadata_schemas(schemas, target_dir):
577576

578577

579578
def extract_external_refs(schema, path):
580-
"""Finds all relative external file references in the schema properties."""
579+
"""Finds all relative external file references in the schema."""
581580
refs = []
582-
props = schema.get("properties", {})
583-
if not isinstance(props, dict):
584-
return refs
585581

586-
for name, data in props.items():
582+
def _scan(name, data):
587583
for node in iter_nodes(data):
588584
if isinstance(node, dict) and "$ref" in node:
589585
ref = node["$ref"]
590586
if "#" not in ref:
591587
abs_path = str((path.parent / ref).resolve())
592588
refs.append((name, abs_path))
589+
590+
props = schema.get("properties", {})
591+
if isinstance(props, dict):
592+
for name, data in props.items():
593+
_scan(name, data)
594+
595+
# Also scan top-level composition keywords (oneOf, anyOf, allOf, items)
596+
for key in ["oneOf", "anyOf", "allOf"]:
597+
if key in schema:
598+
_scan(key, schema[key])
599+
if "items" in schema:
600+
_scan("items", schema["items"])
593601
return refs
594602

595603

@@ -606,23 +614,28 @@ def propagate_needs_transitive(variant_needs, schema_refs, schemas):
606614
continue
607615

608616
for op in list(variant_needs[path]):
609-
for prop_name, child_path in refs:
617+
for ref_name, child_path in refs:
610618
if child_path not in schemas:
611619
continue
612620

613-
# Only propagate if the property isn't 'omit'ted for this op
614-
data = (
615-
schemas[path].get("properties", {}).get(prop_name, {})
616-
)
617-
include, _ = eval_prop_inclusion(
618-
prop_name, data, op, schemas[path].get("required", [])
619-
)
620-
621-
if include:
622-
target_set = variant_needs.setdefault(child_path, set())
623-
if op not in target_set:
624-
target_set.add(op)
625-
changed = True
621+
# For property refs, check if the property is included for this op.
622+
# For non-property refs (oneOf, anyOf, allOf, items), always propagate.
623+
props = schemas[path].get("properties", {})
624+
if ref_name in props:
625+
data = props[ref_name]
626+
include, _ = eval_prop_inclusion(
627+
ref_name,
628+
data,
629+
op,
630+
schemas[path].get("required", []),
631+
)
632+
if not include:
633+
continue
634+
635+
target_set = variant_needs.setdefault(child_path, set())
636+
if op not in target_set:
637+
target_set.add(op)
638+
changed = True
626639

627640

628641
# --- Main Flow ---

src/ucp_sdk/models/schemas/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,3 @@
1515
# generated by datamodel-codegen
1616
# pylint: disable=all
1717
# pyformat: disable
18-

src/ucp_sdk/models/schemas/common/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,3 @@
1515
# generated by datamodel-codegen
1616
# pylint: disable=all
1717
# pyformat: disable
18-

src/ucp_sdk/models/schemas/shopping/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,3 @@
1515
# generated by datamodel-codegen
1616
# pylint: disable=all
1717
# pyformat: disable
18-

src/ucp_sdk/models/schemas/shopping/cart_create_request.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from pydantic import BaseModel, ConfigDict
2222

23-
from .checkout import Checkout as Checkout_1
23+
from .checkout_create_request import CheckoutCreateRequest
2424
from .types import (
2525
attribution_create_request,
2626
buyer_create_request,
@@ -56,7 +56,7 @@ class CartCreateRequest(BaseModel):
5656
"""
5757

5858

59-
class Checkout(Checkout_1):
59+
class Checkout(CheckoutCreateRequest):
6060
"""
6161
Checkout extended with cart capability. Adds cart_id to create_checkout for cart-to-checkout conversion.
6262
"""

src/ucp_sdk/models/schemas/shopping/cart_update_request.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from pydantic import BaseModel, ConfigDict
2222

23-
from .checkout import Checkout as Checkout_1
23+
from .checkout_update_request import CheckoutUpdateRequest
2424
from .types import (
2525
attribution_update_request,
2626
buyer_update_request,
@@ -60,7 +60,7 @@ class CartUpdateRequest(BaseModel):
6060
"""
6161

6262

63-
class Checkout(Checkout_1):
63+
class Checkout(CheckoutUpdateRequest):
6464
"""
6565
Checkout extended with cart capability. Adds cart_id to create_checkout for cart-to-checkout conversion.
6666
"""

src/ucp_sdk/models/schemas/shopping/types/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,3 @@
1515
# generated by datamodel-codegen
1616
# pylint: disable=all
1717
# pyformat: disable
18-
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright 2026 UCP Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# generated by datamodel-codegen
16+
# pylint: disable=all
17+
# pyformat: disable
18+
19+
from __future__ import annotations
20+
21+
from typing import Annotated
22+
23+
from pydantic import Field
24+
from typing_extensions import TypeAliasType
25+
26+
ErrorCodeCreateRequest = TypeAliasType(
27+
"ErrorCodeCreateRequest",
28+
Annotated[
29+
str,
30+
Field(
31+
...,
32+
examples=[
33+
"not_found",
34+
"out_of_stock",
35+
"item_unavailable",
36+
"address_undeliverable",
37+
"payment_failed",
38+
"eligibility_invalid",
39+
"identity_required",
40+
"insufficient_scope",
41+
],
42+
title="Error Code Create Request",
43+
),
44+
],
45+
)
46+
"""
47+
Error code identifying the type of error. Standard errors are defined in specification (see examples), and have standardized semantics; freeform codes are permitted.
48+
"""
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright 2026 UCP Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# generated by datamodel-codegen
16+
# pylint: disable=all
17+
# pyformat: disable
18+
19+
from __future__ import annotations
20+
21+
from typing import Annotated
22+
23+
from pydantic import Field
24+
from typing_extensions import TypeAliasType
25+
26+
ErrorCodeUpdateRequest = TypeAliasType(
27+
"ErrorCodeUpdateRequest",
28+
Annotated[
29+
str,
30+
Field(
31+
...,
32+
examples=[
33+
"not_found",
34+
"out_of_stock",
35+
"item_unavailable",
36+
"address_undeliverable",
37+
"payment_failed",
38+
"eligibility_invalid",
39+
"identity_required",
40+
"insufficient_scope",
41+
],
42+
title="Error Code Update Request",
43+
),
44+
],
45+
)
46+
"""
47+
Error code identifying the type of error. Standard errors are defined in specification (see examples), and have standardized semantics; freeform codes are permitted.
48+
"""
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright 2026 UCP Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# generated by datamodel-codegen
16+
# pylint: disable=all
17+
# pyformat: disable
18+
19+
from __future__ import annotations
20+
21+
from typing import Annotated
22+
23+
from pydantic import Field
24+
from typing_extensions import TypeAliasType
25+
26+
InfoCodeCreateRequest = TypeAliasType(
27+
"InfoCodeCreateRequest",
28+
Annotated[
29+
str,
30+
Field(
31+
...,
32+
examples=[
33+
"identity_optional",
34+
"signal",
35+
"free_shipping",
36+
"not_found",
37+
],
38+
title="Info Code Create Request",
39+
),
40+
],
41+
)
42+
"""
43+
Info code identifying the type of informational message. Standard codes are defined in capability specs (see examples), and have standardized semantics; freeform codes are permitted.
44+
"""

0 commit comments

Comments
 (0)