Skip to content

fix(parse): run the request transform once in parse() - #3616

Open
rasmusfaber wants to merge 1 commit into
openai:mainfrom
rasmusfaber:fix/parse-run-transform-once
Open

fix(parse): run the request transform once in parse()#3616
rasmusfaber wants to merge 1 commit into
openai:mainfrom
rasmusfaber:fix/parse-run-transform-once

Conversation

@rasmusfaber

Copy link
Copy Markdown
  • I understand that this repository is auto-generated and my pull request may not be merged

Changes being requested

For concurrent usage with large payloads, systems can use a disproportionately long time just in the _transform_recursive() method. A more optimal implementation (compile the per-type transform plan once, execute without runtime typing introspection) could speed up performance of transform up to 370x. You would probably want to do that yourself, however, and it might conflict with the migration to Castiron.

There is a tiny, trivial 2x improvement to be had, however:

The hand-written parse() helpers pass the CreateParams union to the request transform, while the generated create() methods dispatch to the concrete Streaming/NonStreaming type. For union annotations, _transform_recursive walks the body once per union member, so parse() requests pay exactly 2x the transform cost of create() requests (measured 1.99-2.01x).

Pass the concrete params type instead, mirroring create().

The transformed body is unchanged, we only skip an unnecessary second walk in _transform_recursive(). Output is verified by differential comparison on large bodies for both APIs.

This is the same fix anthropic-sdk-python shipped for Messages.stream() in v0.122.0 (12c744c8, "run the request transform once in messages.stream()").

Additional context & links

@rasmusfaber
rasmusfaber requested a review from a team as a code owner August 14, 2026 09:18

@ting-hong-shieh ting-hong-shieh left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Validated at 67ed3cad against main/d9029e3a.

Focused checks:

  • .venv/bin/pytest -q -n 0 tests/lib/chat/test_completions.py tests/lib/responses/test_responses.py — 24 passed
  • Ruff lint and format checks on both changed files — passed
  • Mypy on both changed files — passed

I also ran a same-input transform snapshot for Chat non-streaming and Responses with stream omitted, false, and true. The union and concrete transforms produced identical canonical output hashes in all four cases. Recursive transform calls dropped from 187 to 94 for Chat and from 211/215 to 105/108/106 for the three Responses cases.

main is still the PR base, so there is no base drift. GitHub currently reports all three workflows as action_required with no jobs created, so CI has not run yet. I did not call the live API; request serialization was validated locally.

No blocking issues found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants