fix(job): surface review/spend-limited states and cost warning#671
Conversation
ReviewI focused on the hand-written diff ( Bugs / correctness1. Notably, the sibling 2. The Minor / nitpicks
TestsGood coverage for the paths that are implemented: Given finding #1, a test for the As called out in the PR description, no CI job runs Positive notes
|
RapidataJob._wait_for_status waited only for Completed/Failed, so a job that entered ManualApproval or SpendLimited blocked the caller forever (e.g. via get_results). It now raises an informative error naming the state — including the reviewReason when the API returns one, a generic "is being reviewed" message when it doesn't, and a partial-results / top-up hint for SpendLimited. display_progress_bar gets the same guard. assign_job now surfaces the create response's optional costWarning as a Python warning (estimated cost, available balance, shortfall), phrased as an estimate. The job is still created and behavior is otherwise unchanged. Adds pytest + tests covering both hang-fix states (with and without a reviewReason), the cost-warning emission, and the unchanged happy path, plus a docs note in audiences.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: karl <karl@rapidata.ai>
Address code-review findings on the review-states work: - quickstart.md still promised get_results "blocks until the job is complete", which is no longer true for ManualApproval/SpendLimited — point at the new audiences.md section instead. - The polling loops fetched the job for its status, then fetched it again for the review reason (and failure message) when raising. They now fetch the GET output once per iteration and pass it to _raise_for_blocking_status; _get_review_reason is gone. - Blocking-state comparisons use the generated AudienceJobState enum instead of raw strings, matching how RapidataOrder uses OrderState. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: karl <karl@rapidata.ai>
5ffcd2c to
535d8d6
Compare
ReviewSolid fix for a real footgun (jobs hanging forever in What the PR does
Code quality / correctness
Docs
Tests
Security / performance
Overall: clean, well-tested, and appropriately scoped fix for a genuine hang bug. The enum/string mixing in |
| warnings.warn( | ||
| f"Job '{job.name}' has an estimated cost of {cost_warning.estimated_cost:.2f}, " | ||
| f"but the account balance is {cost_warning.available_balance:.2f} — it will " | ||
| f"likely pause about {cost_warning.shortfall:.2f} short of finishing. The job " | ||
| f"was created and runs as far as the balance allows; top up the account to let " | ||
| f"it complete. This is an estimate.", | ||
| stacklevel=3, | ||
| ) |
There was a problem hiding this comment.
why does this not just use a logger?
| @@ -0,0 +1,150 @@ | |||
| """Tests for surfacing job review/spend-limited states and the create cost warning. | |||
There was a problem hiding this comment.
since when do we have test files on the sdk? like i don't mind it in general. but please create a better folder structure than this ^^
Address review feedback from @LinoGiger: - Emit the create-time cost warning via the SDK logger (logger.warning, the repo's user-facing warning convention) instead of warnings.warn. - Move tests into a package layout mirroring src (tests/rapidata_client/{job,audience}/) instead of one flat file, and keep the AudienceJobState-based test helper from the polling refactor. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: karl <karl@rapidata.ai>
|
Thanks @LinoGiger — both addressed in
|
ReviewWent through the diff in detail ( Correctness
Docs
Cost warning
Tests
Nit
Nothing blocking — nice, focused fix with good test coverage and matching docs updates. |
ReviewSolid fix for a real production issue (jobs stuck in Correctness — looks right
One thing worth double-checking: PR description vs. implementationThe PR description says cost warnings are surfaced via a Python
If a real Minor / non-blocking
Nits
Nothing here blocks the change — the core hang-fix and cost-warning logic are correct and well-tested. The |
What & why
Workstream E (Wave 2) of the RFC Job submission: cost warning + transparent review outcomes. Two customer-facing SDK gaps:
Silent hang.
RapidataJob._wait_for_statuswaited only forCompleted/Failed, so a job that enteredManualApprovalorSpendLimitedblocked the caller forever (most visibly viaget_results()). It now raises an informative error instead:reviewReason), and falls back to a generic "is being reviewed" message when it's null (a job can legitimately be under review with no reason yet).display_progress_barhad the identical loop and gets the same guard, so the two entry points behave consistently.Cost warning. When job creation returns the new
costWarning { estimatedCost, availableBalance, shortfall },assign_jobnow emits a Pythonwarnings.warn(estimate, balance, shortfall), phrased as an estimate. The job is still created and behavior is otherwise unchanged — absentcostWarning→ no warning.Follow-up commit folds in code-review findings: the stale "blocks until complete" promise in
quickstart.mdnow points at the new review/cost-warning docs; the polling loops fetch the job GET output once per iteration instead of re-fetching it for the review reason / failure message when raising; and the blocking-state comparisons use the generatedAudienceJobStateenum instead of raw strings (matching howRapidataOrderusesOrderState).Tests
Introduces
pytest(dev dep) andtests/test_job_review_and_cost_warning.py:ManualApprovalwith and without areviewReasonSpendLimited(+display_progress_bar)costWarningemission and the no-warning pathCompleted→ results returned)pyright,black,pytest(7/7), andmkdocs buildall clean; docs notes inaudiences.mdandquickstart.md.Depends on the generated models from Update OpenAPI Schemas #670 — merged, and this branch is now rebased on top of it, so the diff is only the hand-written changes.
Note: no CI job runs pytest today (CI is pyright-only); wiring the new suite into CI is a sensible follow-up.
🔗 Session: https://node-07688719.poseidon.rapidata.internal/
🔗 Review session: https://cli-karl-57b3b766.poseidon.rapidata.internal/