diff --git a/preprocess_schemas.py b/preprocess_schemas.py index 755db30..090b0f7 100644 --- a/preprocess_schemas.py +++ b/preprocess_schemas.py @@ -267,6 +267,107 @@ def preprocess_full_schema(schema, entity_def=None): distribute_properties_to_branches(node) +# --- Dotted $defs Flattening --- + + +def _rewrite_local_defs_refs(node, rename_map): + """Walks a schema tree and rewrites local $defs refs whose target was renamed.""" + prefix = "#/$defs/" + for n in iter_nodes(node): + if not isinstance(n, dict): + continue + ref = n.get("$ref") + if not isinstance(ref, str) or not ref.startswith(prefix): + continue + rest = ref[len(prefix) :] + name, sep, tail = rest.partition("/") + if name in rename_map: + n["$ref"] = prefix + rename_map[name] + (sep + tail if sep else "") + + +def _rewrite_external_defs_refs(schema_path, schema, global_rename_maps): + """Walks a schema tree and rewrites external $defs refs whose target was renamed.""" + path = Path(schema_path) + for n in iter_nodes(schema): + if not isinstance(n, dict): + continue + ref = n.get("$ref") + if not isinstance(ref, str): + continue + if "#" not in ref: + continue + + file_part, fragment_part = ref.split("#", 1) + if not file_part or not file_part.endswith(".json"): + continue + + prefix = "/$defs/" + if not fragment_part.startswith(prefix): + continue + + # Resolve target schema path + target_path = (path.parent / file_part).resolve() + target_path_str = str(target_path) + + if target_path_str not in global_rename_maps: + continue + + rename_map = global_rename_maps[target_path_str] + + rest = fragment_part[len(prefix) :] + name, sep, tail = rest.partition("/") + if name in rename_map: + new_name = rename_map[name] + new_fragment = prefix + new_name + (sep + tail if sep else "") + n["$ref"] = file_part + "#" + new_fragment + + +def flatten_dotted_defs(schema): + """ + Renames $defs keys containing '.' so codegen does not emit nested directories. + + RATIONALE: datamodel-codegen treats dots in $def names as path separators, + so a definition like 'dev.ucp.shopping.checkout' produces + 'dev/ucp/shopping/checkout.py' rather than a class in the parent module. + UCP uses reverse-DNS def names as extension mount points (e.g. an extension + schema's contribution to the base Checkout type), so those classes belong + inline with the rest of the schema's output. + + Strategy: prefer the last dotted component as the new key (giving a clean + class name like 'Checkout'); fall back to dot-replaced-with-underscore + (e.g. 'DevUcpShoppingFulfillment') if the bare tail would collide with + an existing def in the same file. + """ + defs = schema.get("$defs") + if not isinstance(defs, dict): + return {} + + existing = set(defs.keys()) + rename_map = {} + for old in list(defs.keys()): + if "." not in old: + continue + tail = old.rsplit(".", 1)[-1] + if tail and tail not in existing: + new = tail + else: + new = old.replace(".", "_") + if new in existing: + # Both candidates collide; leave as-is rather than risk corruption + continue + rename_map[old] = new + existing.discard(old) + existing.add(new) + + if not rename_map: + return {} + + for old, new in rename_map.items(): + defs[new] = defs.pop(old) + _rewrite_local_defs_refs(schema, rename_map) + return rename_map + + # --- Variant Generation (Create/Update/Complete) --- @@ -532,14 +633,27 @@ def main(): "Entity definition not found! 'ucp.json' must define '$defs.entity'" ) - # Pass 1: Local flattening and find explicit variant markers + global_rename_maps = {} + # Pass 1a: Local flattening, find explicit variant markers, collect renames for p_abs, s in schemas.items(): if "ucp.json" in p_abs or "_request.json" in p_abs: continue + rename_map = flatten_dotted_defs(s) + if rename_map: + global_rename_maps[p_abs] = rename_map preprocess_full_schema(s, entity_def) - # Write back the flattened core schema - save_json(s, Path(p_abs)) + # Pass 1b: Rewrite external references to renamed defs + for p_abs, s in schemas.items(): + if "ucp.json" in p_abs or "_request.json" in p_abs: + continue + _rewrite_external_defs_refs(p_abs, s, global_rename_maps) + + # Pass 1c: Save and extract refs + for p_abs, s in schemas.items(): + if "ucp.json" in p_abs or "_request.json" in p_abs: + continue + save_json(s, Path(p_abs)) schema_refs[p_abs] = extract_external_refs(s, Path(p_abs)) # Check if this schema explicitly asks for variants via 'ucp_request' markers diff --git a/pyproject.toml b/pyproject.toml index 82db8af..00ff05c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ucp-sdk" -version = "0.4.0" +version = "0.4.1" description = "UCP Python SDK" readme = "README.md" license = {file = "LICENSE"} diff --git a/src/ucp_sdk/models/schemas/common/identity_linking/__init__.py b/src/ucp_sdk/models/schemas/common/identity_linking.py similarity index 93% rename from src/ucp_sdk/models/schemas/common/identity_linking/__init__.py rename to src/ucp_sdk/models/schemas/common/identity_linking.py index a2a02d2..a01449c 100644 --- a/src/ucp_sdk/models/schemas/common/identity_linking/__init__.py +++ b/src/ucp_sdk/models/schemas/common/identity_linking.py @@ -22,7 +22,7 @@ from pydantic import BaseModel, ConfigDict, Field, RootModel -from ...shopping.types import description as description_1 +from ..shopping.types import description as description_1 class IdentityLinking(RootModel[Any]): @@ -59,3 +59,10 @@ class ScopeToken(RootModel[str]): """ OAuth scope string formed by joining a capability name and a scope name with a colon: '{capability}:{scope}', e.g. 'dev.ucp.shopping.order:read'. Capability names use reverse-DNS naming; scope names denote the permission granted, defined by each capability's spec (e.g. 'read', 'manage', 'create'). Platforms request these strings verbatim in OAuth 'scope' parameters; issued tokens carry them in the 'scope' claim. """ + + +class IdentityLinking1(RootModel[Any]): + model_config = ConfigDict( + frozen=True, + ) + root: Any diff --git a/src/ucp_sdk/models/schemas/common/identity_linking/dev/__init__.py b/src/ucp_sdk/models/schemas/common/identity_linking/dev/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/common/identity_linking/dev/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/common/identity_linking/dev/ucp/__init__.py b/src/ucp_sdk/models/schemas/common/identity_linking/dev/ucp/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/common/identity_linking/dev/ucp/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/common/identity_linking/dev/ucp/common.py b/src/ucp_sdk/models/schemas/common/identity_linking/dev/ucp/common.py deleted file mode 100644 index 4bce997..0000000 --- a/src/ucp_sdk/models/schemas/common/identity_linking/dev/ucp/common.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable - -from __future__ import annotations - -from typing import Any - -from pydantic import ConfigDict, RootModel - - -class IdentityLinking(RootModel[Any]): - model_config = ConfigDict( - frozen=True, - ) - root: Any diff --git a/src/ucp_sdk/models/schemas/shopping/ap2_mandate/__init__.py b/src/ucp_sdk/models/schemas/shopping/ap2_mandate.py similarity index 82% rename from src/ucp_sdk/models/schemas/shopping/ap2_mandate/__init__.py rename to src/ucp_sdk/models/schemas/shopping/ap2_mandate.py index 5a87c76..e14fa1a 100644 --- a/src/ucp_sdk/models/schemas/shopping/ap2_mandate/__init__.py +++ b/src/ucp_sdk/models/schemas/shopping/ap2_mandate.py @@ -22,6 +22,8 @@ from pydantic import BaseModel, ConfigDict, Field, RootModel +from .checkout import Checkout as Checkout_1 + class Ap2MandateExtension(RootModel[Any]): model_config = ConfigDict( @@ -117,3 +119,35 @@ class ErrorCode( """ Error codes specific to AP2 mandate verification. """ + + +class Ap2(BaseModel): + """ + AP2 extension data including merchant authorization. + """ + + model_config = ConfigDict( + extra="allow", + ) + merchant_authorization: MerchantAuthorization | None = None + """ + Merchant's signature proving checkout terms are authentic. + """ + checkout_mandate: CheckoutMandate | None = None + """ + SD-JWT+kb proving user authorized this checkout. + """ + + +class Checkout(Checkout_1): + """ + Checkout extended with AP2 mandate support. + """ + + model_config = ConfigDict( + extra="allow", + ) + ap2: Ap2 | None = None + """ + AP2 extension data including merchant authorization. + """ diff --git a/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/__init__.py b/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/ucp/__init__.py b/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/ucp/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/ucp/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/ucp/shopping.py b/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/ucp/shopping.py deleted file mode 100644 index 312a17a..0000000 --- a/src/ucp_sdk/models/schemas/shopping/ap2_mandate/dev/ucp/shopping.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable - -from __future__ import annotations - -from pydantic import BaseModel, ConfigDict - -from ....checkout import Checkout as Checkout_1 -from ... import CheckoutMandate, MerchantAuthorization - - -class Ap2(BaseModel): - """ - AP2 extension data including merchant authorization. - """ - - model_config = ConfigDict( - extra="allow", - ) - merchant_authorization: MerchantAuthorization | None = None - """ - Merchant's signature proving checkout terms are authentic. - """ - checkout_mandate: CheckoutMandate | None = None - """ - SD-JWT+kb proving user authorized this checkout. - """ - - -class Checkout(Checkout_1): - """ - Checkout extended with AP2 mandate support. - """ - - model_config = ConfigDict( - extra="allow", - ) - ap2: Ap2 | None = None - """ - AP2 extension data including merchant authorization. - """ diff --git a/src/ucp_sdk/models/schemas/shopping/buyer_consent/__init__.py b/src/ucp_sdk/models/schemas/shopping/buyer_consent.py similarity index 84% rename from src/ucp_sdk/models/schemas/shopping/buyer_consent/__init__.py rename to src/ucp_sdk/models/schemas/shopping/buyer_consent.py index c23994e..4162d93 100644 --- a/src/ucp_sdk/models/schemas/shopping/buyer_consent/__init__.py +++ b/src/ucp_sdk/models/schemas/shopping/buyer_consent.py @@ -22,7 +22,8 @@ from pydantic import BaseModel, ConfigDict, Field, RootModel -from ..types.buyer import Buyer as Buyer_1 +from .checkout import Checkout as Checkout_1 +from .types.buyer import Buyer as Buyer_1 class BuyerConsentExtension(RootModel[Any]): @@ -73,3 +74,17 @@ class Buyer(Buyer_1): """ Consent tracking fields. """ + + +class Checkout(Checkout_1): + """ + Checkout extended with consent tracking via buyer object. + """ + + model_config = ConfigDict( + extra="allow", + ) + buyer: Buyer | None = None + """ + Buyer with consent tracking. + """ diff --git a/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/__init__.py b/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/ucp/__init__.py b/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/ucp/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/ucp/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/ucp/shopping.py b/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/ucp/shopping.py deleted file mode 100644 index 6b59298..0000000 --- a/src/ucp_sdk/models/schemas/shopping/buyer_consent/dev/ucp/shopping.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable - -from __future__ import annotations - -from pydantic import ConfigDict - -from ....checkout import Checkout as Checkout_1 -from ... import Buyer - - -class Checkout(Checkout_1): - """ - Checkout extended with consent tracking via buyer object. - """ - - model_config = ConfigDict( - extra="allow", - ) - buyer: Buyer | None = None - """ - Buyer with consent tracking. - """ diff --git a/src/ucp_sdk/models/schemas/shopping/discount/__init__.py b/src/ucp_sdk/models/schemas/shopping/discount.py similarity index 86% rename from src/ucp_sdk/models/schemas/shopping/discount/__init__.py rename to src/ucp_sdk/models/schemas/shopping/discount.py index 8b2f9f3..fc355f1 100644 --- a/src/ucp_sdk/models/schemas/shopping/discount/__init__.py +++ b/src/ucp_sdk/models/schemas/shopping/discount.py @@ -22,8 +22,10 @@ from pydantic import BaseModel, ConfigDict, Field, RootModel -from ..types import amount as amount_1 -from ..types import reverse_domain_name +from .cart import Cart as Cart_1 +from .checkout import Checkout as Checkout_1 +from .types import amount as amount_1 +from .types import reverse_domain_name class DiscountExtension(RootModel[Any]): @@ -116,3 +118,25 @@ class DiscountsObject(BaseModel): """ Discounts successfully applied (code-based and automatic). """ + + +class Cart(Cart_1): + """ + Cart extended with discount capability. + """ + + model_config = ConfigDict( + extra="allow", + ) + discounts: DiscountsObject | None = None + + +class Checkout(Checkout_1): + """ + Checkout extended with discount capability. + """ + + model_config = ConfigDict( + extra="allow", + ) + discounts: DiscountsObject | None = None diff --git a/src/ucp_sdk/models/schemas/shopping/discount/dev/__init__.py b/src/ucp_sdk/models/schemas/shopping/discount/dev/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/shopping/discount/dev/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/shopping/discount/dev/ucp/__init__.py b/src/ucp_sdk/models/schemas/shopping/discount/dev/ucp/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/shopping/discount/dev/ucp/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/shopping/discount/dev/ucp/shopping.py b/src/ucp_sdk/models/schemas/shopping/discount/dev/ucp/shopping.py deleted file mode 100644 index 23d4fcf..0000000 --- a/src/ucp_sdk/models/schemas/shopping/discount/dev/ucp/shopping.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable - -from __future__ import annotations - -from pydantic import ConfigDict - -from ....cart import Cart as Cart_1 -from ....checkout import Checkout as Checkout_1 -from ... import DiscountsObject - - -class Cart(Cart_1): - """ - Cart extended with discount capability. - """ - - model_config = ConfigDict( - extra="allow", - ) - discounts: DiscountsObject | None = None - - -class Checkout(Checkout_1): - """ - Checkout extended with discount capability. - """ - - model_config = ConfigDict( - extra="allow", - ) - discounts: DiscountsObject | None = None diff --git a/src/ucp_sdk/models/schemas/shopping/fulfillment/__init__.py b/src/ucp_sdk/models/schemas/shopping/fulfillment.py similarity index 77% rename from src/ucp_sdk/models/schemas/shopping/fulfillment/__init__.py rename to src/ucp_sdk/models/schemas/shopping/fulfillment.py index 46fba84..8b34540 100644 --- a/src/ucp_sdk/models/schemas/shopping/fulfillment/__init__.py +++ b/src/ucp_sdk/models/schemas/shopping/fulfillment.py @@ -22,8 +22,9 @@ from pydantic import ConfigDict, Field, RootModel -from ..types import ( - fulfillment, +from .checkout import Checkout as Checkout_1 +from .types import fulfillment as fulfillment_1 +from .types import ( fulfillment_available_method, fulfillment_group, fulfillment_method, @@ -41,6 +42,13 @@ class FulfillmentExtension(RootModel[Any]): """ +class DevUcpShoppingFulfillment(RootModel[Any]): + model_config = ConfigDict( + frozen=True, + ) + root: Any + + class FulfillmentAvailableMethod( RootModel[fulfillment_available_method.FulfillmentAvailableMethod] ): @@ -71,8 +79,22 @@ class FulfillmentMethod(RootModel[fulfillment_method.FulfillmentMethod]): root: fulfillment_method.FulfillmentMethod -class Fulfillment(RootModel[fulfillment.Fulfillment]): +class Fulfillment(RootModel[fulfillment_1.Fulfillment]): model_config = ConfigDict( frozen=True, ) - root: fulfillment.Fulfillment + root: fulfillment_1.Fulfillment + + +class Checkout(Checkout_1): + """ + Checkout extended with hierarchical fulfillment. + """ + + model_config = ConfigDict( + extra="allow", + ) + fulfillment: Fulfillment | None = None + """ + Fulfillment details. + """ diff --git a/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/__init__.py b/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/ucp/__init__.py b/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/ucp/__init__.py deleted file mode 100644 index 1252d6b..0000000 --- a/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/ucp/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable diff --git a/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/ucp/shopping.py b/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/ucp/shopping.py deleted file mode 100644 index 2d58bb8..0000000 --- a/src/ucp_sdk/models/schemas/shopping/fulfillment/dev/ucp/shopping.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright 2026 UCP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# generated by datamodel-codegen -# pylint: disable=all -# pyformat: disable - -from __future__ import annotations - -from typing import Any - -from pydantic import ConfigDict, RootModel - -from ....checkout import Checkout as Checkout_1 -from ... import Fulfillment as Fulfillment_1 - - -class Fulfillment(RootModel[Any]): - model_config = ConfigDict( - frozen=True, - ) - root: Any - - -class Checkout(Checkout_1): - """ - Checkout extended with hierarchical fulfillment. - """ - - model_config = ConfigDict( - extra="allow", - ) - fulfillment: Fulfillment_1 | None = None - """ - Fulfillment details. - """ diff --git a/src/ucp_sdk/models/schemas/shopping/types/fulfillment_method_update_request.py b/src/ucp_sdk/models/schemas/shopping/types/fulfillment_method_update_request.py index 33b953f..712477f 100644 --- a/src/ucp_sdk/models/schemas/shopping/types/fulfillment_method_update_request.py +++ b/src/ucp_sdk/models/schemas/shopping/types/fulfillment_method_update_request.py @@ -36,11 +36,11 @@ class FulfillmentMethodUpdateRequest(BaseModel): model_config = ConfigDict( extra="allow", ) - id: str + id: str | None = None """ Unique fulfillment method identifier. """ - type: Literal["shipping", "pickup"] + type: Literal["shipping", "pickup"] | None = None """ Fulfillment method type. """