Skip to content
Open
24 changes: 12 additions & 12 deletions rest/python/server/generated_routes/ucp_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@

from typing import Annotated
from fastapi import APIRouter, Body, Header
import ucp_sdk.models.schemas.shopping.checkout_create_req
import ucp_sdk.models.schemas.shopping.checkout_resp
import ucp_sdk.models.schemas.shopping.checkout_update_req
import ucp_sdk.models.schemas.shopping.checkout_create_request
import ucp_sdk.models.schemas.shopping.checkout
import ucp_sdk.models.schemas.shopping.checkout_update_request
import ucp_sdk.models.schemas.shopping.order
import ucp_sdk.models.schemas.shopping.payment_create_req
import ucp_sdk.models.schemas.shopping.payment_resp
import ucp_sdk.models.schemas.shopping.payment_create_request
import ucp_sdk.models.schemas.shopping.payment

router = APIRouter()


@router.post(
"/checkout-sessions",
response_model=ucp_sdk.models.schemas.shopping.checkout_resp.CheckoutResponse,
response_model=ucp_sdk.models.schemas.shopping.checkout.Checkout,
status_code=201,
operation_id="create_checkout",
summary="Create Checkout",
)
async def create_checkout(
body: Annotated[
ucp_sdk.models.schemas.shopping.checkout_create_req.CheckoutCreateRequest,
ucp_sdk.models.schemas.shopping.checkout_create_request.CheckoutCreateRequest,
Body(...),
],
authorization: str = Header(None, alias="Authorization"),
Expand All @@ -42,7 +42,7 @@ async def create_checkout(

@router.get(
"/checkout-sessions/{id}",
response_model=ucp_sdk.models.schemas.shopping.checkout_resp.CheckoutResponse,
response_model=ucp_sdk.models.schemas.shopping.checkout.Checkout,
status_code=200,
operation_id="get_checkout",
summary="Get Checkout",
Expand All @@ -67,15 +67,15 @@ async def get_checkout(

@router.put(
"/checkout-sessions/{id}",
response_model=ucp_sdk.models.schemas.shopping.checkout_resp.CheckoutResponse,
response_model=ucp_sdk.models.schemas.shopping.checkout.Checkout,
status_code=200,
operation_id="update_checkout",
summary="Update Checkout",
)
async def update_checkout(
id: str,
body: Annotated[
ucp_sdk.models.schemas.shopping.checkout_update_req.CheckoutUpdateRequest,
ucp_sdk.models.schemas.shopping.checkout_update_request.CheckoutUpdateRequest,
Body(...),
],
authorization: str = Header(None, alias="Authorization"),
Expand All @@ -96,7 +96,7 @@ async def update_checkout(

@router.post(
"/checkout-sessions/{id}/complete",
response_model=ucp_sdk.models.schemas.shopping.checkout_resp.CheckoutResponse,
response_model=ucp_sdk.models.schemas.shopping.checkout.Checkout,
status_code=200,
operation_id="complete_checkout",
summary="Complete Checkout",
Expand All @@ -122,7 +122,7 @@ async def complete_checkout(

@router.post(
"/checkout-sessions/{id}/cancel",
response_model=ucp_sdk.models.schemas.shopping.checkout_resp.CheckoutResponse,
response_model=ucp_sdk.models.schemas.shopping.checkout.Checkout,
status_code=200,
operation_id="cancel_checkout",
summary="Cancel Checkout",
Expand Down
58 changes: 29 additions & 29 deletions rest/python/server/integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,34 @@
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import delete
from ucp_sdk.models.schemas.shopping import checkout_create_req
from ucp_sdk.models.schemas.shopping import payment_create_req
from ucp_sdk.models.schemas.shopping.ap2_mandate import (
CheckoutResponseWithAp2 as Ap2Checkout,
)
from ucp_sdk.models.schemas.shopping.buyer_consent_resp import (
from ucp_sdk.models.schemas.shopping import checkout_create_request as checkout_create_req
from ucp_sdk.models.schemas.shopping import payment_create_request as payment_create_req
from ucp_sdk.models.schemas.shopping.ap2_mandate import Checkout as Ap2Checkout
from ucp_sdk.models.schemas.shopping.buyer_consent import (
Checkout as BuyerConsentCheckoutResp,
)
from ucp_sdk.models.schemas.shopping.discount_resp import (
from ucp_sdk.models.schemas.shopping.discount import (
Checkout as DiscountCheckoutResp,
)
from ucp_sdk.models.schemas.shopping.fulfillment_create_req import Fulfillment
from ucp_sdk.models.schemas.shopping.fulfillment_resp import (
from ucp_sdk.models.schemas.shopping.fulfillment import (
Checkout as Fulfillment,
)
from ucp_sdk.models.schemas.shopping.fulfillment import (
Checkout as FulfillmentCheckout,
)
from ucp_sdk.models.schemas.shopping.order import PlatformConfig
from ucp_sdk.models.schemas.shopping.payment_data import PaymentData
from ucp_sdk.models.schemas.shopping.order import PlatformSchema
from ucp_sdk.models.schemas.shopping.payment import Payment as PaymentData
from ucp_sdk.models.schemas.shopping.types import card_payment_instrument
from ucp_sdk.models.schemas.shopping.types import fulfillment_destination_req
from ucp_sdk.models.schemas.shopping.types import fulfillment_group_create_req
from ucp_sdk.models.schemas.shopping.types import fulfillment_method_create_req
from ucp_sdk.models.schemas.shopping.types import fulfillment_req
from ucp_sdk.models.schemas.shopping.types import item_create_req
from ucp_sdk.models.schemas.shopping.types import line_item_create_req
from ucp_sdk.models.schemas.shopping.types import payment_handler_create_req
from ucp_sdk.models.schemas.shopping.types import fulfillment_destination as fulfillment_destination_req
from ucp_sdk.models.schemas.shopping.types import fulfillment_group_create_request as fulfillment_group_create_req
from ucp_sdk.models.schemas.shopping.types import fulfillment_method_create_request as fulfillment_method_create_req
from ucp_sdk.models.schemas.shopping.types import fulfillment as fulfillment_req
from ucp_sdk.models.schemas.shopping.types import item_create_request as item_create_req
from ucp_sdk.models.schemas.shopping.types import line_item_create_request as line_item_create_req
from ucp_sdk.models.schemas.shopping.types import payment_handler as payment_handler_create_req
from ucp_sdk.models.schemas.shopping.types import payment_instrument
from ucp_sdk.models.schemas.shopping.types import shipping_destination_req
from ucp_sdk.models.schemas.shopping.types import token_credential_resp
from ucp_sdk.models.schemas.shopping.types import shipping_destination as shipping_destination_req
from ucp_sdk.models.schemas.shopping.types import token_credential as token_credential_resp

FLAGS = flags.FLAGS

Expand All @@ -71,7 +71,7 @@ class TestCheckout(
):
"""Checkout model supporting Fulfillment, Discount, and AP2 extensions."""

platform: PlatformConfig | None = None
platform: PlatformSchema | None = None


class IntegrationTest(absltest.TestCase):
Expand Down Expand Up @@ -238,8 +238,8 @@ def _create_checkout_payload(
)

# Hierarchical Fulfillment Construction
destination = fulfillment_destination_req.FulfillmentDestinationRequest(
root=shipping_destination_req.ShippingDestinationRequest(
destination = fulfillment_destination_req.FulfillmentDestination(
root=shipping_destination_req.ShippingDestination(
id="dest_1", address_country="US"
)
)
Expand All @@ -253,7 +253,7 @@ def _create_checkout_payload(
groups=[group],
)
fulfillment = Fulfillment(
root=fulfillment_req.FulfillmentRequest(methods=[method])
root=fulfillment_req.Fulfillment(methods=[method])
)

return checkout_create_req.CheckoutCreateRequest(
Expand All @@ -266,7 +266,7 @@ def _create_checkout_payload(

def _create_payment_payload(self) -> PaymentData:
"""Create a payment payload using SDK models."""
credential = token_credential_resp.TokenCredentialResponse(
credential = token_credential_resp.TokenCredential(
type="token", token="success_token"
)
instrument = card_payment_instrument.CardPaymentInstrument(
Expand All @@ -278,10 +278,10 @@ def _create_payment_payload(self) -> PaymentData:
last_digits="1234",
credential=credential,
)
return PaymentData(
payment_data=payment_instrument.PaymentInstrument(root=instrument),
risk_signals={},
)
return {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain the rationale?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The client post (lines 306-310) require the direct json object or a dictionary. They don't serialize pydantic models, so if we the method returns a class here it would need to be converted or unpacked with "model_dump" like it was before. This is cleaner as it avoids the double conversion.

"payment_data": payment_instrument.PaymentInstrument(root=instrument),
"risk_signals": {},
}

def test_single_item_checkout(self) -> None:
"""Test the full lifecycle of a single item checkout."""
Expand Down
36 changes: 17 additions & 19 deletions rest/python/server/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,36 @@
objects used by the sample server implementation.
"""

from ucp_sdk.models.schemas.shopping.ap2_mandate import (
CheckoutResponseWithAp2 as Ap2Checkout,
from ucp_sdk.models.schemas.shopping.ap2_mandate import Checkout as Ap2Checkout
from ucp_sdk.models.schemas.shopping.buyer_consent import (
Checkout as BuyerConsentCheckoutResp,
)
from ucp_sdk.models.schemas.shopping.buyer_consent_create_req import (
from ucp_sdk.models.schemas.shopping.buyer_consent import (
Checkout as BuyerConsentCheckoutCreate,
)
from ucp_sdk.models.schemas.shopping.buyer_consent_resp import (
Checkout as BuyerConsentCheckoutResp,
)
from ucp_sdk.models.schemas.shopping.buyer_consent_update_req import (
from ucp_sdk.models.schemas.shopping.buyer_consent import (
Checkout as BuyerConsentCheckoutUpdate,
)
from ucp_sdk.models.schemas.shopping.discount_create_req import (
Checkout as DiscountCheckoutCreate,
)
from ucp_sdk.models.schemas.shopping.discount_resp import (
from ucp_sdk.models.schemas.shopping.discount import (
Checkout as DiscountCheckoutResp,
)
from ucp_sdk.models.schemas.shopping.discount_update_req import (
Checkout as DiscountCheckoutUpdate,
from ucp_sdk.models.schemas.shopping.discount import (
Checkout as DiscountCheckoutCreate,
)
from ucp_sdk.models.schemas.shopping.fulfillment_create_req import (
Checkout as FulfillmentCreateRequest,
from ucp_sdk.models.schemas.shopping.discount import (
Checkout as DiscountCheckoutUpdate,
)
from ucp_sdk.models.schemas.shopping.fulfillment_resp import (
from ucp_sdk.models.schemas.shopping.fulfillment import (
Checkout as FulfillmentCheckout,
)
from ucp_sdk.models.schemas.shopping.fulfillment_update_req import (
from ucp_sdk.models.schemas.shopping.fulfillment import (
Checkout as FulfillmentCreateRequest,
)
from ucp_sdk.models.schemas.shopping.fulfillment import (
Checkout as FulfillmentUpdateRequest,
)
from ucp_sdk.models.schemas.shopping.order import Order
from ucp_sdk.models.schemas.shopping.order import PlatformConfig
from ucp_sdk.models.schemas.shopping.order import PlatformSchema


class UnifiedOrder(Order):
Expand All @@ -65,7 +63,7 @@ class UnifiedCheckout(
):
"""Checkout model supporting various extensions."""

platform: PlatformConfig | None = None
platform: PlatformSchema | None = None


class UnifiedCheckoutCreateRequest(
Expand Down
2 changes: 1 addition & 1 deletion rest/python/server/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ packages = ["."]

[tool.uv.sources]
# The relative path is stored here
ucp-sdk = { path = "../../../../sdk/python/", editable = true }
ucp-sdk = { path = "python-sdk/", editable = true }

[tool.ruff]
line-length = 80
Expand Down
6 changes: 3 additions & 3 deletions rest/python/server/routes/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import uuid
from fastapi import APIRouter
from fastapi import Request
from ucp_sdk.models.discovery.profile_schema import UcpDiscoveryProfile
from ucp_sdk.models.schemas.ucp import BusinessSchema

router = APIRouter()

Expand All @@ -31,7 +31,7 @@

@router.get(
"/.well-known/ucp",
response_model=UcpDiscoveryProfile,
response_model=BusinessSchema,
summary="Get Merchant Profile",
)
async def get_merchant_profile(request: Request):
Expand All @@ -45,4 +45,4 @@ async def get_merchant_profile(request: Request):
"{{ENDPOINT}}", str(request.base_url).rstrip("/")
).replace("{{SHOP_ID}}", SHOP_ID)

return UcpDiscoveryProfile(**json.loads(profile_json))
return BusinessSchema(**json.loads(profile_json))
14 changes: 7 additions & 7 deletions rest/python/server/routes/ucp_implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
from pydantic import BaseModel
from pydantic import HttpUrl
from services.checkout_service import CheckoutService
from ucp_sdk.models.schemas.shopping.ap2_mandate import Ap2CompleteRequest
from ucp_sdk.models.schemas.shopping.ap2_mandate import Checkout as Ap2CompleteRequest
from ucp_sdk.models.schemas.shopping.order import Order
from ucp_sdk.models.schemas.shopping.order import PlatformConfig
from ucp_sdk.models.schemas.shopping.payment_create_req import (
from ucp_sdk.models.schemas.shopping.order import PlatformSchema
from ucp_sdk.models.schemas.shopping.payment_create_request import (
PaymentCreateRequest,
)
from ucp_sdk.models.schemas.shopping.types.payment_instrument import (
Expand All @@ -57,7 +57,7 @@ class UcpConfig(BaseModel):
class Capability(BaseModel):
"""UCP capability definition."""

config: UcpConfig | None = None
platform: PlatformSchema | None = None


class UcpProfile(BaseModel):
Expand Down Expand Up @@ -129,14 +129,14 @@ async def create_checkout(
"""Create Checkout Implementation."""
# Convert generated model to Unified model which the service expects
# Note: `platform` is no longer in UnifiedCheckoutCreateRequest
# We construct PlatformConfig separately if headers are present
# We construct PlatformSchema separately if headers are present
req_dict = checkout_req.model_dump(exclude_unset=True, by_alias=True)
unified_req = models.UnifiedCheckoutCreateRequest(**req_dict)

platform_config = None
webhook_url = await extract_webhook_url(common_headers.ucp_agent)
if webhook_url:
platform_config = PlatformConfig(webhook_url=webhook_url)
platform_config = PlatformSchema(webhook_url=webhook_url)

result = await checkout_service.create_checkout(
unified_req, idempotency_key, platform_config
Expand Down Expand Up @@ -177,7 +177,7 @@ async def update_checkout(
platform_config = None
webhook_url = await extract_webhook_url(common_headers.ucp_agent)
if webhook_url:
platform_config = PlatformConfig(webhook_url=webhook_url)
platform_config = PlatformSchema(webhook_url=webhook_url)

result = await checkout_service.update_checkout(
checkout_id, unified_req, idempotency_key, platform_config
Expand Down
Loading