feat(data-warehouse): implement scale_ai import source - #70026
Conversation
|
Hey @Gilbert09! 👋 It looks like your git author email on this PR isn't your
You can fix it for this repo with: git config user.email "you@posthog.com"Or set it globally with |
|
Reviews (1): Last reviewed commit: "feat(data-warehouse): implement scale_ai..." | Re-trigger Greptile |
estefaniarabadan
left a comment
There was a problem hiding this comment.
Isolated new data-warehouse source scaffold — self-contained under its own source directory with only the expected shared-registry additions (SOURCES.md, generated_configs.py, icon), tests included, CI green. Reviewed as part of a batch. LGTM 👍
Fill in the scaffolded Scale AI (api.scale.com/v1) warehouse source: a ResumableSource over the tasks, batches, and projects endpoints with HTTP Basic auth, cursor/offset pagination through the tracked session, and incremental sync where the API exposes a genuine server-side timestamp filter. Generated-By: PostHog Code Task-Id: 060615cf-0580-4892-b999-3daece9245e5
Type-annotation-only fixes for the Python code quality (mypy) job: - cast the _FakeResumableManager to ResumableSourceManager[ScaleAIResumeConfig] at the get_rows call site - widen _collect's pages parameter to dict[Any, Any] so mixed-value fixture dicts are accepted - pass the required response= argument to requests.HTTPError Generated-By: PostHog Code Task-Id: 76e6309e-19ad-4bf9-8db5-393d88128e2c
402e14e to
753402d
Compare
🤖 CI report
|
| File | Patch | Uncovered changed lines |
|---|---|---|
products/warehouse_sources/backend/temporal/data_imports/sources/scale_ai/scale_ai.py |
98.3% | 193, 252 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 29282187645 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
warehouse_sources |
███████████████████░ 95.5% |
208,790 / 218,632 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
Problem
Scale AI (data labeling / RLHF) was scaffolded as an unreleased warehouse source stub but had no sync logic. Teams using Scale for labeling want their tasks, batches, and projects in the PostHog Data warehouse so they can join operational labeling data with product analytics.
Why: turn the registered-but-empty
scale_aistub into a working connector so the data is syncable.Changes
Implements the
scale_aisource end-to-end against the v1 REST API (api.scale.com/v1, HTTP Basic auth with the API key as username):ResumableSourceover three endpoints, declared insettings.py:tasks—next_tokencursor pagination; incremental onupdated_at(server-sideupdated_after) orcreated_at(start_time); primary keytask_id.batches—limit/offsetpagination; incremental oncreated_at(start_time); primary keyname.projects— single non-paginated list; full refresh; primary keyname.scale_ai.py: all HTTP goes throughmake_tracked_session(),tenacityretries on 429/5xx/transient,next_token/offsetresume state saved after each yielded batch, andget_non_retryable_errors()for 401/403.sort_mode="desc"everywhere (Scale returns newest-first bycreated_atand exposes no sort control), so the incremental watermark is persisted only at job end — correct for tasks, which filter onupdated_atbut arrive increated_atorder.created_atfield;canonical_descriptions.pyfrom the official API docs;lists_tables_without_credentials = Trueso the docs render the table catalog.unreleasedSource=TruewithreleaseStatus=ALPHA. Regeneratedgenerated_configs.py(singleapi_keyfield) and updatedSOURCES.md.Only
supports_incremental=Truewhere the API has a real server-side timestamp filter; projects ship full-refresh only.Notes / follow-ups
updated_after+cursor assumption is documented inline with a conservative fallback path noted.iconPathstill points atscale_ai.png— needs a real asset added tofrontend/public/services/.contents/docs/cdp/sources/scale-ai.md, matchingdocsUrl) still needs to land in the posthog.com repo, which was not available in this checkout;audit_source_docswas therefore not run.How did you test this code?
Added and ran two test modules (52 tests, all passing):
tests/test_scale_ai.py— transport: incremental-field→server-param mapping,_extract_docsshape handling, cursor pagination + current-page checkpoint + resume, offset pagination + short-page termination + resume, single-fetch projects, retry/status handling, credential-status mapping,SourceResponseprimary keys /descsort / partitioning.tests/test_scale_ai_source.py— source class: config identity/release, secret field shape, schema list + incremental/PK per endpoint, documented-tables catalog, credential validation, non-retryable error matching, pipeline plumbing (incremental cursor dropped on full refresh).Also ran the repo-wide
test_source_categories.pyguard (1506 passing) andruff check/ruff format. Did not run a live end-to-end sync (no Scale API key).Docs update
Doc must be added to posthog.com (see notes above).
🤖 Agent context
Autonomy: Fully autonomous
Authored with Claude Code. Invoked the
/implementing-warehouse-sourcesand/documenting-warehouse-sourcesskills; used the Klaviyo (resumable cursor) and GitHub (desc + incremental) sources as references. Key decisions: choseResumableSourcebecause tasks expose anext_tokencursor and a server-sideupdated_afterfilter; settled onsort_mode="desc"after confirming (via the pipeline'supdate_incremental_field_values) that desc defers watermark persistence to job end, which is the only safe option given tasks filter onupdated_atbut sort bycreated_at; regeneratedgenerated_configs.pyvia the management command and reverted unrelated pre-existing drift so the diff is a singleapi_keyline.Created with PostHog Code