Skip to content

feat(data-warehouse): implement scale_ai import source - #70026

Merged
talyn-app[bot] merged 2 commits into
masterfrom
posthog-code/scale-ai-source
Jul 13, 2026
Merged

feat(data-warehouse): implement scale_ai import source#70026
talyn-app[bot] merged 2 commits into
masterfrom
posthog-code/scale-ai-source

Conversation

@Gilbert09

Copy link
Copy Markdown
Member

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_ai stub into a working connector so the data is syncable.

Changes

Implements the scale_ai source end-to-end against the v1 REST API (api.scale.com/v1, HTTP Basic auth with the API key as username):

  • ResumableSource over three endpoints, declared in settings.py:
    • tasksnext_token cursor pagination; incremental on updated_at (server-side updated_after) or created_at (start_time); primary key task_id.
    • batcheslimit/offset pagination; incremental on created_at (start_time); primary key name.
    • projects — single non-paginated list; full refresh; primary key name.
  • Transport in scale_ai.py: all HTTP goes through make_tracked_session(), tenacity retries on 429/5xx/transient, next_token/offset resume state saved after each yielded batch, and get_non_retryable_errors() for 401/403.
  • sort_mode="desc" everywhere (Scale returns newest-first by created_at and exposes no sort control), so the incremental watermark is persisted only at job end — correct for tasks, which filter on updated_at but arrive in created_at order.
  • Partitioning by the stable created_at field; canonical_descriptions.py from the official API docs; lists_tables_without_credentials = True so the docs render the table catalog.
  • Kept behind unreleasedSource=True with releaseStatus=ALPHA. Regenerated generated_configs.py (single api_key field) and updated SOURCES.md.

Only supports_incremental=True where the API has a real server-side timestamp filter; projects ship full-refresh only.

Notes / follow-ups

  • API verification: endpoint shapes are from the official docs and a live unauthenticated probe (confirms Basic auth + error shape). Authenticated pagination/incremental behavior could not be curl-verified without a live key; the updated_after+cursor assumption is documented inline with a conservative fallback path noted.
  • Icon: no logo asset committed (no Logo.dev key available, per instructions no placeholder/hardcoded key). iconPath still points at scale_ai.png — needs a real asset added to frontend/public/services/.
  • Docs: the user-facing doc (contents/docs/cdp/sources/scale-ai.md, matching docsUrl) still needs to land in the posthog.com repo, which was not available in this checkout; audit_source_docs was 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_docs shape handling, cursor pagination + current-page checkpoint + resume, offset pagination + short-page termination + resume, single-fetch projects, retry/status handling, credential-status mapping, SourceResponse primary keys / desc sort / 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.py guard (1506 passing) and ruff 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-sources and /documenting-warehouse-sources skills; used the Klaviyo (resumable cursor) and GitHub (desc + incremental) sources as references. Key decisions: chose ResumableSource because tasks expose a next_token cursor and a server-side updated_after filter; settled on sort_mode="desc" after confirming (via the pipeline's update_incremental_field_values) that desc defers watermark persistence to job end, which is the only safe option given tasks filter on updated_at but sort by created_at; regenerated generated_configs.py via the management command and reverted unrelated pre-existing drift so the diff is a single api_key line.


Created with PostHog Code

@github-actions

Copy link
Copy Markdown
Contributor

Hey @Gilbert09! 👋

It looks like your git author email on this PR isn't your @posthog.com address (owerstom@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@greptile-apps

greptile-apps Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "feat(data-warehouse): implement scale_ai..." | Re-trigger Greptile

@trunk-io

trunk-io Bot commented Jul 10, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@estefaniarabadan estefaniarabadan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@Gilbert09
Gilbert09 force-pushed the posthog-code/scale-ai-source branch from 402e14e to 753402d Compare July 13, 2026 20:23
@github-actions

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Backend coverage — 99.0% of changed backend lines covered — 2 uncovered

🧪 Backend test coverage

Patch coverage — changed backend lines (products + core): ████████████████████ 99.0% (411 / 413)

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.

@talyn-app
talyn-app Bot merged commit f379998 into master Jul 13, 2026
213 checks passed
@talyn-app
talyn-app Bot deleted the posthog-code/scale-ai-source branch July 13, 2026 21:00
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 13, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-13 21:27 UTC Run
prod-us ✅ Deployed 2026-07-13 21:38 UTC Run
prod-eu ✅ Deployed 2026-07-13 21:40 UTC Run

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.

2 participants