mirror of
https://github.com/Comfy-Org/comfy-python-sdk.git
synced 2026-11-04 23:37:47 +00:00
[PR #63] [MERGED] fix: keep protocol errors off the public surface, add AsyncOutput.to_stream, widen the 429 retry #63
Labels
No labels
audit:ai-readiness
audit:community
audit:github
audit:health-scoring
audit:policy
audit:release
audit:supply-chain
effort:medium
effort:small
effort:small
effort:trivial
priority:nice-to-have
priority:nice-to-have
priority:recommended
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/comfy-python-sdk#63
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/comfy-python-sdk/pull/63
Author: @wei-hai
Created: 8/21/2026
Status: ✅ Merged
Merged: 8/23/2026
Merged by: @wei-hai
Base:
main← Head:fix/error-contract-and-429-retry📝 Commits (4)
28f68a9fix: keep protocol errors off the public surface, add AsyncOutput.to_stream, widen the 429 retry0a5bc48fix: tighten retry budgets and error contract coverage852a21bfix: preserve final retries and partial stream writes8e977b4Merge branch 'main' into fix/error-contract-and-429-retry📊 Changes
12 files changed (+513 additions, -41 deletions)
View changed files
📝
README.md(+11 -3)📝
src/comfy_sdk/assets.py(+4 -2)📝
src/comfy_sdk/client.py(+33 -12)📝
src/comfy_sdk/jobs.py(+7 -5)📝
src/comfy_sdk/outputs.py(+42 -15)📝
tests/conftest.py(+51 -0)📝
tests/test_assets.py(+1 -2)📝
tests/test_async.py(+59 -2)📝
tests/test_download_and_workflows.py(+30 -0)➕
tests/test_error_contract.py(+143 -0)📝
tests/test_jobs.py(+85 -0)➕
tests/test_sync_async_parity.py(+47 -0)📄 Description
Fixes #62. Three defects, one untested guarantee: nothing asserted that the public surface only raises
comfy_sdkexceptions.1. Ten entry points leaked
comfy_low.errors.ApiErrortranslating()was skipped on all fourOutput/AsyncOutputdownload methods, bothAssetFactory.get, bothJobFactory.get, and the non-501 re-raise inevents().Both modules export an unrelated class named
NotFound, so the documented pattern silently never fired:2.
AsyncOutputwas missingto_streamSix of the seven sync/async class pairs matched; this one was off by exactly that method, against a README promising the surfaces are identical.
3.
submit()gave up on a retryable 429The gate was
isinstance(err, QueueFull)— the server's error code — but the contract disambiguates a retryable 429 by status +Retry-After.queue_full, with headerqueue_full, no headerdeployment_not_ready(cold start)The new predicate is
exc.http_status == 429 and (exc.retry_after is not None or exc.code == "queue_full"), in both loops — forward-compatible with any future 429 code.Hardening
Retry-Afteris untrusted input and reachedsleep()unbounded: the budget was checked before the sleep, never against its duration, soRetry-After: 10000000produced one ~115-day sleep past a 60s budget. A negative value diverged —time.sleep(-5)raised an uncaughtValueError,asyncio.sleep(-5)spun the loop with no pause. Now clamped to the remaining budget and floored at zero.Also fixes
Retry-After: 0being treated as absent by the oldoridiom (it slept the full default), now pinned by an assertion.Risk
Callers catching
comfy_low.errors.ApiErroraround those ten entry points must catch thecomfy_sdkexception instead — what the README already documents. Two pre-existing tests were asserting the leak itself and were retargeted.Verification
ruff,mypy,pytest(163 passed, 4 skipped),pytest --cov, codegen drift. Each new test confirmed to fail against the pre-fix source. New tests assert on a monkeypatched sleep argument — none wait.Out of scope, left as follow-ups from the issue's checklist:
from_url,Preview.to_pil(), the_CODE_BY_STATUSfallback branch, the README escape hatches,backoff_schedule,head_asset_by_hash, and the_BY_CODE/to_sdk_errorcompleteness guard.Summary by CodeRabbit
Bug Fixes
Documentation
Tests
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.