mirror of
https://github.com/Comfy-Org/comfy-python-sdk.git
synced 2026-11-04 23:37:47 +00:00
[PR #210] docs(errors): list rate_limited explicitly as the fourth code both surfaces share #211
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#211
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/210
Author: @mattmillerai
Created: 10/9/2026
Status: 🔄 Open
Base:
main← Head:matt/be-19964-rate-limited-by-code📝 Commits (2)
826aa2fdocs(errors): list rate_limited explicitly as the fourth code both surfaces share07253badocs(errors): cover status-derived shared codes, fold changelog bullet, fix _BY_CODE comment📊 Changes
5 files changed (+73 additions, -28 deletions)
View changed files
📝
CHANGELOG.md(+4 -0)📝
README.md(+13 -6)📝
src/comfy_sdk/exceptions.py(+19 -10)📝
src/comfy_sdk/router_exceptions.py(+15 -9)📝
tests/test_error_mapping.py(+22 -3)📄 Description
ELI-5
When the jobs/assets API says "you're making requests too fast" (
rate_limited), the SDK already raisedcomfy_sdk.router_exceptions.RateLimited— but only because a lookup in one table missed and it fell through to a second one. This PR writes that mapping down on purpose, in the first table, next to the three other codes that work the same way, and fixes the docs that still said "three". What gets raised doesn't change.What changed
src/comfy_sdk/exceptions.py:"rate_limited": RateLimitedadded to_BY_CODE(next toinsufficient_credits),RateLimitedimported from.router_exceptionsand added to__all__(sorted) as the other shared classes are. The_BY_CODEcomment,_class_forstep 1, theto_sdk_errorcomment and the__all__comment now say four, and the_BY_CODEcomment says why: the v2 contract's account rate limit (components/responses/RateLimited) and Router'srate_limitedbucket are the same windowed allowance spelled the same way, so one class serves both and.error_type == "rate_limited"is set from either surface.src/comfy_sdk/router_exceptions.py: module docstring names four shared buckets includingrate_limited;RateLimited's docstring keeps the Router meaning and theConcurrencyLimitExceededcontrast, adds the v2 jobs/assets use, and narrows "detailnames the window" to the Router surface._spec_meaning_digestuntouched (it hashes the Router spec'smeaning, not this docstring;test_router_spec_contract.pyandcheck_drift.pyboth pass).README.md: the shared-names paragraph lists four and says a jobs/assets call throttled with429 rate_limitedraisesRateLimited; the "never reached Router → plainComfyError" sentence gets a clause for responses that land on one of the four shared codes — a v2 envelope naming one, or a bare401/402/403the status table maps to one — soexcept RouterErrorfiring is not by itself proof Router answered.tests/test_error_mapping.py:rate_limitedadded totest_a_bucket_both_surfaces_spell_keeps_its_v2_class; newtest_a_v2_envelope_rate_limited_is_the_shared_router_class(noerror_type, asserts exact type,RouterErrorancestry,code,error_type,retry_after), with a comment marking the sharing as deliberate.CHANGELOG.md: one bullet in Unreleased's existing### Changedsection.Judgment calls
comfy_sdkre-exportsUnauthorized/Forbidden/InsufficientCreditsat the root, but its own comment says per-bucket Router classes stay incomfy_sdk.router_exceptions; addingcomfy_sdk.RateLimitedwould be new public surface, which is out of scope. The README says so explicitly ("and the first three bycomfy_sdktoo").rate_limitedremoved fromtest_a_router_only_bucket_raises_its_typed_class. It's no longer a Router-only bucket, so leaving it there would make that test's name wrong. Its assertions (exact type,code,http_status,retry_after == 7at 429) are all covered again by the new test, so no coverage is lost.### Changedsection rather than a second heading. It also mentions the newcomfy_sdk.exceptions.RateLimitedre-export.Residual
tests/test_head_refusal.pyand theHEAD /assets/by-hash429 synthesis belong to open PR #208 and weren't touched or run here (that file doesn't exist onmain). When #208 lands, itstype(exc) is RateLimitedassertion now resolves through_BY_CODEinstead of the fall-through. Same class, so no change is expected._BY_CODElines. Expect a trivial merge conflict on adjacent dict lines, nothing semantic.main: removing the new_BY_CODEentry still passes because the fall-through gives the same class. The proof that behavior didn't change is thattests/test_job_metadata.py(which already pins v2rate_limited→RateLimited) passes unmodified.tests/integration/test_gateway_e2e.pyskips without live credentials, so it wasn't exercised.Provenance
ruff check,ruff format --check,mypy srcall cleancomfy_low.errors._CODE_BY_STATUS(401/402/403 map to the shared codes; 429 maps toqueue_full, notrate_limited)build-check, codegen drift (no generated or spec file touched)🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.