fix(rest/python): determine currency server side instead of reading it from the create request - #156
Open
vishkaty wants to merge 1 commit into
Conversation
…t from the create request
A checkout create that follows the schema returns 500. checkout.json annotates
`currency` with `ucp_request: omit`, so a conformant platform does not send it,
and the generated CheckoutCreateRequest has no such field. create_checkout reads
`checkout_req.currency` regardless, which raises AttributeError on the pydantic
extra lookup and surfaces as Internal Server Error.
Reproduction against main, with the minimal conformant body:
POST /checkout-sessions
{"line_items": [{"item": {"id": "bouquet_roses"}, "quantity": 1}]}
-> 500
The same request with `"currency": "USD"` added returns 201, because
extra="allow" makes the attribute resolve.
The update path had the same read at checkout_service.py:432 and failed the
same way. Since the spec assigns the determination to the business, an update
no longer takes currency from the request either.
The Node sample already sets currency server side, so this brings the Python
sample in line with it.
Adds two integration tests covering create and update with the conformant body.
The existing tests all build payloads through _create_checkout_payload, which
sets id and currency, so this path was never exercised.
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.
What I ran into
A checkout create that follows the schema returns 500 from the Python sample
server. The same request succeeds once a field the schema says to omit is added,
which is what kept this off the radar.
Observed against main (2e5b77c)
Fresh clone, documented setup, seeded flower shop database:
Server log:
Adding
"currency": "USD"to the same body returns 201.Why I think the minimal body is the correct one
source/schemas/shopping/checkout.jsonannotatescurrencywithucp_request: omit, and describes it as the merchant market determination,derived from address, context and geo IP.
CheckoutCreateRequestin the SDK hasno
currencyfield for that reason, andline_itemsis its only requiredmember. So a platform following the schema sends exactly the body above, and
that is the body that fails.
create_checkoutreadscheckout_req.currencyanyway. Because the model setsextra="allow", that attribute only resolves when a client sends a field theschema told it to omit, and raises AttributeError otherwise.
Scope
I swept for other reads of request fields marked omit and found one more, the
same pattern on the update path:
checkout_service.py:310create,currency=checkout_req.currencycheckout_service.py:432update,if checkout_req.currency:checkout_service.py:198create,model_dump(exclude={... "currency" ...})rest/nodejs/src/api/checkout.ts:553The Node sample already determines currency itself, so this brings the Python
sample in line with it rather than introducing a new convention.
On the update path I removed the client driven override rather than making the
read tolerant, because the spec assigns the determination to the business. If
you would rather keep accepting a platform supplied currency there, I am happy
to switch that hunk to a tolerant read instead. That is a judgement call and
yours to make.
Why CI did not catch it
Every integration test builds its payload through
_create_checkout_payload,which sets
idandcurrency. Both areucp_request: omitfields, andextra="allow"keeps them, socheckout_req.currencyalways resolved and theconformant path was never exercised.
Verification
uv run --directory rest/python/server pytest: 20 passed, including the twonew tests
so the tests are load bearing rather than incidental
python-server-tests.yml: database init, server boot,and
simple_happy_path_client.pyend to end, exit 0 with no 500 in the logpre-commit runclean, ruff and ruff format bothPlease let me know if the framing or the update path call looks wrong to you and
I will adjust.