Skip to content

feat(job): require a capability below 10 responses per datapoint - #979

Closed
LucStr wants to merge 2 commits into
mainfrom
feat(job)/require-a-capability-below-10-responses
Closed

LucStr wants to merge 2 commits into
mainfrom
feat(job)/require-a-capability-below-10-responses

Conversation

@LucStr

@LucStr LucStr commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Why

The backend now rejects jobs with fewer than 10 responses per datapoint unless the organization holds the LowResponseCount capability (sibling PR: RapidataAI/rapidata-backend#5733). The SDK posts the job definition only after every datapoint is uploaded, so a backend-only check would fail after the whole upload. This checks first and tells the customer how to get it enabled.

Flow

flowchart LR
  sdk["create_*_job_definition / job_def.responses_per_datapoint = n"]:::changed ==>|"n < 10: GET /connect/userinfo (capabilities, platform_relations)"| auth["Identity: userinfo"]
  sdk -->|"POST /dataset + datapoints"| ds[("Dataset")]
  sdk -->|"POST /job/definition, POST revision"| order["Order: job definition"]
  order ==>|"400: At least 10 responses per datapoint ..."| err["RapidataError.__str__"]:::changed
  classDef new fill:#d3f9d8,stroke:#2f9e44,color:#000
  classDef changed fill:#fff3bf,stroke:#f08c00,color:#000
  classDef removed fill:#ffe3e3,stroke:#e03131,color:#000,stroke-dasharray:4
Loading
API Change Before → After
LowResponseCountError (exported from rapidata) new — → ValueError subclass with requested, minimum; message ends with the backend's exact text
RapidataError.__str__ changed Reasons: {"errors": {...}} → one Field: message line per validation message

Decisions

  • Capability comes from the capabilities claim of /connect/userinfo, not GET /customers/{id}/capabilities — that endpoint is staff-only (Platform.Viewer), so customers would always get 403. Userinfo returns the grants of the token's org, the same scope the backend enforces; platform admins (platform_relations: admin) pass, as on the backend.
  • Fails open: a lookup error or non-200 logs at debug and leaves the decision to the backend. Only grants are cached per client, so an org enabled mid-session works without a new RapidataClient; a refusal raises anyway.
  • Only SimpleWorkflow jobs are gated, matching the backend; ranking (responses_per_comparison) is permanently exempt. The generated client is untouched — the enum value arrives with the next automated OpenAPI update.

Verified

tests/rapidata_client/job/test_response_minimum.py covers the gate, cache, no-upload-before-raise and setter paths, plus error rendering; pyright src/rapidata/rapidata_client clean; mkdocs build clean. Skill updated (SKILL.md task design rule 1, reference.md).

🔗 Session: node-4d496828

🤖 Generated with Claude Code

Checks the caller's LowResponseCount capability (userinfo claims) before any
upload and raises LowResponseCountError with the backend's message. Ranking is
not gated. Validation errors now render one 'field: message' line each.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: luca@rapidata.ai <25279790+LucStr@users.noreply.github.com>
@LucStr
LucStr marked this pull request as ready for review October 26, 2026 15:49
@LucStr
LucStr requested a review from LinoGiger as a code owner October 26, 2026 15:49
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: luca@rapidata.ai <25279790+LucStr@users.noreply.github.com>
@LinoGiger LinoGiger closed this Oct 28, 2026
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