Skip to content

fix: decode SSE incrementally without limiting event size - #3687

Merged
apcha-oai merged 2 commits into
mainfrom
apcha/sse-frame-bounds
Aug 19, 2026
Merged

fix: decode SSE incrementally without limiting event size#3687
apcha-oai merged 2 commits into
mainfrom
apcha/sse-frame-bounds

Conversation

@apcha-oai

@apcha-oai apcha-oai commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Share an amortized-linear incremental SSE line framer between synchronous and asynchronous decoding.
  • Process complete lines as they arrive so comments and ignored fields are discarded before the event finishes.
  • Preserve historical unlimited line/event sizes, CR/LF/CRLF framing, UTF-8 chunking, and response cleanup. No new size-limit API, dependencies, exported client APIs, or [DONE] drain changes.

This removes quadratic prefix copying and unnecessary whole-frame retention. It does not impose a memory bound on arbitrarily large data events or unfinished lines.

Validation

  • 62 focused streaming/framing tests passed, including synchronous and asynchronous events larger than 64 MiB, fragmented and unterminated input, all newline forms, transport interruption, and cancellation.
  • Ruff, targeted Mypy, targeted Pyright, and git diff --check passed.
  • Final separate local review (round 3 of 3) was clean at d3667578e1a4e8da9d1962bfd403d98f4a0f945c; its exhaustive short-input CR/LF fragmentation matrix also passed.

Independent PR against public main. Please confirm this handwritten shared-runtime patch is preserved in the next Castiron Python candidate; no schema or generation-metadata change is needed.

@apcha-oai
apcha-oai marked this pull request as ready for review August 19, 2026 21:03
@apcha-oai
apcha-oai requested a review from a team as a code owner August 19, 2026 21:03
Comment thread tests/test_sse_framing.py Fixed
@apcha-oai
apcha-oai enabled auto-merge August 19, 2026 21:03
@openai-sdks

openai-sdks Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

OkTest Summary

237/237 SDK tests passed in 11.718s for Python SDK PR #3687.

Test results — 42 files
Test Result Time
tests/chat-completions-complex-body.test.ts ✅ Passed 178ms
tests/chat-completions-create.test.ts ✅ Passed 257ms
tests/chat-completions-stream.test.ts ✅ Passed 131ms
tests/files-content-binary.test.ts ✅ Passed 242ms
tests/files-create-multipart.test.ts ✅ Passed 190ms
tests/files-list-pagination.test.ts ✅ Passed 145ms
tests/initialize-config.test.ts ✅ Passed 194ms
tests/instance-isolation.test.ts ✅ Passed 185ms
tests/models-list.test.ts ✅ Passed 134ms
tests/responses-background-lifecycle.test.ts ✅ Passed 220ms
tests/responses-body-method-errors.test.ts ✅ Passed 357ms
tests/responses-cancel-timeout.test.ts ✅ Passed 190ms
tests/responses-cancel.test.ts ✅ Passed 229ms
tests/responses-compact-retries.test.ts ✅ Passed 475ms
tests/responses-compact.test.ts ✅ Passed 255ms
tests/responses-create-advanced-stream.test.ts ✅ Passed 137ms
tests/responses-create-advanced.test.ts ✅ Passed 269ms
tests/responses-create-disconnect.test.ts ✅ Passed 1.269s
tests/responses-create-errors.test.ts ✅ Passed 255ms
tests/responses-create-malformed-api-responses.test.ts ✅ Passed 338ms
tests/responses-create-retries.test.ts ✅ Passed 265ms
tests/responses-create-stream-failures.test.ts ✅ Passed 137ms
tests/responses-create-stream-timeout.test.ts ✅ Passed 238ms
tests/responses-create-stream-wire.test.ts ✅ Passed 3.962s
tests/responses-create-stream.test.ts ✅ Passed 96ms
tests/responses-create-terminal-states.test.ts ✅ Passed 238ms
tests/responses-create-timeout.test.ts ✅ Passed 220ms
tests/responses-create.test.ts ✅ Passed 255ms
tests/responses-delete.test.ts ✅ Passed 270ms
tests/responses-input-items-errors.test.ts ✅ Passed 403ms
tests/responses-input-items-list.test.ts ✅ Passed 345ms
tests/responses-input-items-options.test.ts ✅ Passed 426ms
tests/responses-input-tokens-count-timeout.test.ts ✅ Passed 260ms
tests/responses-input-tokens-count.test.ts ✅ Passed 279ms
tests/responses-malformed-inputs.test.ts ✅ Passed 3.039s
tests/responses-not-found-errors.test.ts ✅ Passed 293ms
tests/responses-parse.test.ts ✅ Passed 453ms
tests/responses-retrieve-retries.test.ts ✅ Passed 330ms
tests/responses-retrieve.test.ts ✅ Passed 364ms
tests/responses-stored-method-errors.test.ts ✅ Passed 581ms
tests/retry-behavior.test.ts ✅ Passed 3.014s
tests/sdk-error-shape.test.ts ✅ Passed 334ms

View OkTest run #32303447214

SDK merge (d7b8609a200f) · head (d3667578e1a4) · base (600aa8daade4) · OkTest (2b1bdfd25e98)

@apcha-oai
apcha-oai disabled auto-merge August 19, 2026 21:04
@apcha-oai apcha-oai changed the title fix: bound incremental SSE decoding fix: decode SSE incrementally without limiting event size Aug 19, 2026
Comment thread tests/test_sse_framing.py
assert decoder._data == ["partial"]
task.cancel()
with pytest.raises(asyncio.CancelledError):
await task

@HAYDEN-OAI HAYDEN-OAI left a comment

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.

Reviewed the incremental SSE framing and decoding paths, including newline and chunk boundaries, fragmented UTF-8, event-state handling, large-payload compatibility, cancellation, and synchronous/asynchronous parity. No substantive correctness, compatibility, reliability, or security issues found.

@jbeckwith-oai jbeckwith-oai left a comment

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.

Independent two-pass review confirms the incremental SSE decoder preserves unlimited line/event sizes, fragmented UTF-8 and CR/LF framing, multiline data, existing completion semantics, sync/async compatibility, cancellation, and response cleanup without unnecessary full-frame retention. Realistic >64 MiB regressions and substantive CI/CodeQL pass. Automated no-effect reports on awaited tasks are false positives; no actionable findings.

@apcha-oai
apcha-oai added this pull request to the merge queue Aug 19, 2026
Merged via the queue into main with commit 2598d53 Aug 19, 2026
21 checks passed
@apcha-oai
apcha-oai deleted the apcha/sse-frame-bounds branch August 19, 2026 22:13
@openai-sdks openai-sdks Bot mentioned this pull request Aug 19, 2026
leiandy pushed a commit to leiandy/openai-python that referenced this pull request Aug 26, 2026
Automated Release PR
---


##
[3.4.0](openai/openai-python@v3.3.1...v3.4.0)
(2026-08-25)


### Features

* **api:** Add obfuscation field to ChatCompletionChunk
([openai#3690](openai#3690))
([c7d8e1d](openai@c7d8e1d))
* **api:** add project residency configuration and cost quantity units
([openai#3726](openai#3726))
([bc4f8ef](openai@bc4f8ef))


### Bug Fixes

* **api:** encode Realtime call offers and session configuration
([openai#3736](openai#3736))
([555ac48](openai@555ac48))
* apply consistent origin checks to WebSocket redirects
([openai#3693](openai#3693))
([1b324d0](openai@1b324d0))
* **azure:** encode deployment names consistently
([openai#3683](openai#3683))
([689538d](openai@689538d))
* **azure:** keep provider validation errors value-free
([openai#3691](openai#3691))
([72529c0](openai@72529c0))
* **azure:** resolve one authentication mode
([openai#3689](openai#3689))
([e3d0681](openai@e3d0681))
* compute custom-code summaries from trusted workflow code
([openai#3692](openai#3692))
([2b5868d](openai@2b5868d))
* create upload example fixtures in private directories
([openai#3686](openai#3686))
([f36e6f7](openai@f36e6f7))
* decode SSE incrementally without limiting event size
([openai#3687](openai#3687))
([2598d53](openai@2598d53))
* keep Python SDK diagnostics metadata-only
([openai#3685](openai#3685))
([600aa8d](openai@600aa8d))
* Preserve Azure authentication boundaries across transports
([openai#3684](openai#3684))
([06ef57c](openai@06ef57c))
* preserve the configured TLS hostname
([openai#3694](openai#3694))
([aa5fbc4](openai@aa5fbc4))
* preserve WebSocket send queue byte accounting during flush
([openai#3688](openai#3688))
([96f966d](openai@96f966d))


### Chores

* **api:** Clarify image background docs and preview support
([openai#3703](openai#3703))
([bedb9a7](openai@bedb9a7))
* **api:** document supported image generation models
([openai#3695](openai#3695))
([8edd9ae](openai@8edd9ae))
* **api:** move chat validation tests out of generated code
([openai#3698](openai#3698))
([9d3ba20](openai@9d3ba20))
* **api:** move webhook tests out of generated code
([openai#3700](openai#3700))
([04ecb3c](openai@04ecb3c))
* **api:** remove redundant generated formatting
([openai#3696](openai#3696))
([5ac1e03](openai@5ac1e03))
* **api:** remove redundant generated test edits
([openai#3697](openai#3697))
([351ef84](openai@351ef84))
* **api:** Update SDK generation metadata only
([openai#3716](openai#3716))
([e43b422](openai@e43b422))
* set a ceiling for Python SDK customization
([openai#3714](openai#3714))
([04d5d79](openai@04d5d79))


### Documentation

* **api:** restore generated ChatKit API index
([openai#3705](openai#3705))
([4534106](openai@4534106))
* standardize Python SDK vulnerability disclosure policy
([openai#3642](openai#3642))
([1fc0a21](openai@1fc0a21))


### Refactors

* **api:** isolate audio response format selection
([openai#3701](openai#3701))
([ece4324](openai@ece4324))
* **api:** isolate vector-store polling helpers
([openai#3713](openai#3713))
([a002ef3](openai@a002ef3))
* **api:** move file processing polling into SDK-owned helpers
([openai#3712](openai#3712))
([5f20c51](openai@5f20c51))
* **api:** share embedding response decoding
([openai#3699](openai#3699))
([50de9af](openai@50de9af))
* **api:** share webhook signature verification
([openai#3704](openai#3704))
([e14ac34](openai@e14ac34))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: openai-sdks[bot] <284451331+openai-sdks[bot]@users.noreply.github.com>
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.

3 participants