Skip to content

Commit 4f0e1b8

Browse files
committed
feat: implement the URL search params serialization standard
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
1 parent 4f9cc47 commit 4f0e1b8

4 files changed

Lines changed: 960 additions & 0 deletions

File tree

README.rst

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ Contents
6565

6666
* `Setting the endpoint`_
6767

68+
* `Serializing URL search params`_
69+
6870
* `Development and Testing`_
6971

7072
* `Quickstart`_
@@ -436,6 +438,49 @@ e.g., testing or proxy setups.
436438

437439
Either pass the ``endpoint`` option to the constructor, or set the ``SEAM_ENDPOINT`` environment variable.
438440

441+
Serializing URL search params
442+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
443+
444+
The Seam API parses URL search params as complex types.
445+
This SDK implements the `Seam URL search params serialization standard`_,
446+
which defines how the Seam SDKs serialize objects to URL search params.
447+
Use it directly when building requests to the Seam API by hand:
448+
449+
.. code-block:: python
450+
451+
from seam import serialize_url_search_params
452+
453+
serialize_url_search_params(
454+
{
455+
"name": "Dax",
456+
"age": 27,
457+
"is_admin": True,
458+
"tags": ["cars", "planes"],
459+
}
460+
)
461+
# => 'age=27&is_admin=true&name=Dax&tags=cars&tags=planes'
462+
463+
Params are sorted by name, so equivalent input always produces the same query string.
464+
Nested dicts are serialized to dot-path keys, e.g., ``{"a": {"b": 1}}`` becomes ``a.b=1``.
465+
Params set to ``None`` are serialized to an empty value, e.g., ``a=``,
466+
while params set to ``seam.UNDEFINED`` are removed.
467+
A param that cannot be represented raises a ``seam.UnserializableParamError``.
468+
469+
To merge serialized params into existing params, use ``update_url_search_params``:
470+
471+
.. code-block:: python
472+
473+
from seam import UrlSearchParams, update_url_search_params
474+
475+
search_params = UrlSearchParams("?foo=bar")
476+
477+
update_url_search_params(search_params, {"name": "Dax"})
478+
479+
str(search_params)
480+
# => 'foo=bar&name=Dax'
481+
482+
.. _Seam URL search params serialization standard: https://github.com/seamapi/url-search-params-serializer
483+
439484
Development and Testing
440485
-----------------------
441486

seam/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,10 @@
1515
)
1616
from .seam_webhook import SeamWebhook
1717
from svix.webhooks import WebhookVerificationError as SeamWebhookVerificationError
18+
from .utils.url_search_params_serializer import (
19+
UNDEFINED,
20+
UnserializableParamError,
21+
UrlSearchParams,
22+
serialize_url_search_params,
23+
update_url_search_params,
24+
)

0 commit comments

Comments
 (0)