feat: implement the URL search params serialization standard - #597
Open
razor-x wants to merge 3 commits into
Open
feat: implement the URL search params serialization standard#597razor-x wants to merge 3 commits into
razor-x wants to merge 3 commits into
Conversation
Port @seamapi/url-search-params-serializer to Python so the SDK can serialize objects to URL search params for HTTP GET requests. Output is byte-for-byte identical to the reference implementation: - Values are encoded with the application/x-www-form-urlencoded serializer, which differs from urllib in its treatment of "*" and "~". - Params are sorted by name, compared by UTF-16 code unit. - Floats are formatted using the ECMAScript Number::toString algorithm, which differs from repr for integral floats and around the exponent notation thresholds. Python has no undefined, so UNDEFINED is provided as the sentinel for a removed param, while None serializes to an empty value as null does. Temporal.Instant and Date both map to datetime, where a naive datetime is interpreted as UTC and microseconds are truncated to millisecond precision. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PpqwDhZmyikGbjmCPqFW2A
The Seam API distinguishes an omitted param from a param explicitly set to null: in an update request, an omitted param leaves the current value unchanged while a null param unsets it, and some endpoints accept null as a meaningful filter value. Python has a single absence value, so route methods omitted both cases and there was no way to send null. For example, access_grants.list documents null as a filter for Access Grants without an access_grant_key, but passing None dropped the filter and returned every Access Grant. Add the NULL sentinel for a param explicitly set to null. Since sending null is rarely intended and unsetting a value cannot be undone, None keeps meaning the safe option of omitting the param, so this adds the capability without changing the behavior of any existing call. The existing generated route methods need no change: they already omit params set to None, and the client now replaces any remaining NULL sentinel with None so that json serializes it to null. NULL works at any depth, e.g., to clear a single key of an object param. Bind the URL search params serializer to the same convention, replacing its UNDEFINED sentinel: None is JavaScript undefined and is removed, while NULL is JavaScript null and serializes to an empty value. NULL is typed as Any so it may be passed to any param without a type error. Once blueprint exposes isNullable on Parameter, codegen can type nullable params precisely instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PpqwDhZmyikGbjmCPqFW2A
Blueprint now reports isNullable for request parameters, so codegen can distinguish the params the Seam API documents as nullable from the rest. Type a nullable param as Union[T, Null] so it accepts the NULL sentinel, and leave every other param as it was. This makes NULL checkable. Previously NULL had to be typed as Any to be passed anywhere, which meant a type checker could not report sending null to a param that does not accept it. NULL is now typed as Null, so passing it to a non-nullable param such as devices.update(is_managed=...) is an error while access_grants.list(access_grant_key=NULL) is accepted. Reading isNullable requires blueprint 1.4.0 or later, which turns an untyped property from a warning into an error. The pinned types release leaves submit_args untyped for /seam/connect_webview/v1/submit, so generation fails against it; bump types to the next release, which defines that type and adds the between parameter to events.list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PpqwDhZmyikGbjmCPqFW2A
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.
Port @seamapi/url-search-params-serializer to Python so the SDK can
serialize objects to URL search params for HTTP GET requests.
Output is byte-for-byte identical to the reference implementation:
serializer, which differs from urllib in its treatment of "*" and "~".
which differs from repr for integral floats and around the exponent
notation thresholds.
Python has no undefined, so UNDEFINED is provided as the sentinel for a
removed param, while None serializes to an empty value as null does.
Temporal.Instant and Date both map to datetime, where a naive datetime is
interpreted as UTC and microseconds are truncated to millisecond
precision.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01PpqwDhZmyikGbjmCPqFW2A