feat: add account API key support across Python clients - #58
feat: add account API key support across Python clients#58KillerQueen-Z wants to merge 3 commits into
Conversation
|
Superseded — main already has this feature, and it is released. #59 landed The two designs are not equivalent, and #59 is the fuller one:
So I'd close this rather than rebase it. One thing here is worth keeping, though, and it is not in main: Porting it needs two adjustments to main's design: It also asserts Whoever picks this up: closing #58 and opening a small PR with just that test file (plus #61's fix, so the retry_after assertion can stay) gets the value without the conflict. |
|
Closing this superseded API implementation: #59 is already merged, and rebasing this parallel design would duplicate and conflict with main. Follow-up client fixes are tracked in #60. Per the review, the remaining wire-contract, credential-redaction and accepted-job no-resubmission tests should be ported to the current design together with Retry-After issue #61; closing this PR does not claim that work is complete. Keeping the branch and test history available for that port. |
Closes #61. api.blockrun.ai answers a rate limit with Retry-After and the gateway sets it deliberately: it is what turns a refused request into a caller that waits instead of one that spins against the limit the header exists to prevent. It never survived the SDK boundary — APIError carried message, status_code and response, and `grep -rn retry_after blockrun_llm/` returned nothing. Every consumer on the account rail had to guess or spin. APIError gains `retry_after`, kept as the raw header string. The HTTP spec allows both a delay in seconds and an HTTP-date, and inventing a number for the date form would be worse than handing back what arrived; `retry_after_seconds` parses the delay form and answers None for everything else, including a negative value. `retry_after_of()` is the single reader. It tolerates a response with no headers attribute, because it runs inside an error path and raising there would replace the real failure with an AttributeError about the failure. Migrated all 75 raise sites that hold a response, across 14 files. The remaining 15 have no response to read — poll-budget timeouts, a missing poll_url, stream probes that exhausted retries — so they carry None because there is nothing to carry, not because they were skipped. The issue warns that a partial migration is worse than none; this one is complete. portrait.py, realface.py and video.py each carried a byte-identical private `_raise_api_error`. They now delegate to one `raise_api_error` in validation.py, so the next change to how failures are reported lands in three places at once rather than two out of three. 45 new cases, including the 30 client x method table from #58 that this issue asked to salvage. Mutants that die: the reader always returning None, the shared helper dropping the header, a negative delay passing through, the seconds parser inventing a number for an unparseable value, and stripping every retry_after kwarg from any one client file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QMLNFbR6Jg2HBFpRUGBjyh
Users can use BlockRun account keys across synchronous/asynchronous chat and streaming, named media/data clients, and the native Anthropic adapter without loading or creating a wallet. Generic APIClient/AsyncAPIClient cover Responses and other account endpoints. Explicit wallet credentials preserve wallet mode; setup_agent_client prefers Solana for new wallets and preserves existing chain choices.
Shared account authentication binds credentials to the configured origin, rejects redirects, strips payment proofs, bypasses wallet caches and preserves status/Retry-After. Account 402 errors never invoke x402. The Anthropic account adapter defaults to max_retries=0 so an ambiguous 429/5xx does not replay a potentially billed POST. Accepted jobs recover from temporary polling errors by GETting the original full poll_url within the original timeout. Auth/credit/rate-limit errors remain visible.
Add synchronous Solana client context-manager cleanup, align Surf pricing estimates, and replace “timeout means no payment” text. README covers registration, keys, credits, Activity, signed polling URLs, independent wallet/account balances and wallet switching. It explicitly distinguishes this source checkout from currently published releases. The optional Anthropic extra remains below 1 because this adapter uses httpx transports.
Validation:
Local provider/storage responses are fixtures. This update does not claim every live provider/model or real on-chain wallet payment was tested, and does not publish a package or deploy the gateway.