Skip to content

feat: build catalog-only streams for config-free discover (create_catalog_stream) - #1237

Draft
Aaron ("AJ") Steers (aaronsteers) wants to merge 3 commits into
aj/feat/unprivileged-discover-for-declarative-static-schemasfrom
devin/1792446479-catalog-only-discover
Draft

Aaron ("AJ") Steers (aaronsteers) wants to merge 3 commits into
aj/feat/unprivileged-discover-for-declarative-static-schemasfrom
devin/1792446479-catalog-only-discover

Conversation

@aaronsteers

Copy link
Copy Markdown
Member

Overview

👉 TL;DR: Lets sources like GitHub return their catalog without a config, even when building their full streams needs credentials or a start date.

Without a config, ConcurrentDeclarativeSource.discover now builds streams through a new catalog-only vector, ModelToComponentFactory.create_catalog_stream. It shares _build_schema_loader, _resolve_cursor_field and DefaultStream.as_airbyte_stream() with the full vector in create_default_stream.

Stacked on #559:

Changes

  • _build_schema_loader: the schema-loader block moves out of create_default_stream, unchanged. Both vectors call it.
  • _resolve_cursor_field: the cursor-field resolution, which was copied into the datetime, incrementing-count and per-partition cursor builders, now lives in one helper (catalog-defined override first, otherwise the manifest cursor_field interpolated with $parameters).
  • create_catalog_stream: returns a DefaultStream with the same name, schema loader, primary key, cursor field and supports_file_transfer as create_default_stream. It never builds requesters, authenticators, partition routers or real cursors. Its _CatalogOnlyPartitionGenerator raises if anything tries to read it.
    • StateDelegatingStream: uses the full refresh stream when there is no state, the same as create_state_delegating_stream.
    • Unsupported incremental_sync types raise, the same as the full vector.
  • ConcurrentDeclarativeSource.discover: uses _catalog_streams() only when config is empty and check_config_during_discover is False, which is feat: Add config-free discover for declarative sources with static catalogs #559's config-free path. Configured discover, check and read still go through streams().

Review Spotlight

Reviewers with limited time, please review first:

Risks

  • The catalog-only vector skips everything that does not feed the catalog. If a future change in create_default_stream alters a catalog field (name, schema, primary key, cursor field, file transfer), create_catalog_stream has to change too. The parity tests are the guard.
  • If a schema loader or cursor field interpolates config, config-free discover still fails with feat: Add config-free discover for declarative sources with static catalogs #559's config_error. It never returns a partial catalog.

Evidence

Check Result
source-github: config-free discover compared with dummy-token configured discover 39 / 39 streams, every AirbyteStream equal
Config-free sweep, 516 manifest-only sources (#559 alone → this PR) catalog 306 → 504; config required by design 10 → 10; build failures 200 → 2
Sources that returned a catalog on #559 none broke, none changed stream count
Unit tests parity of config-free vs configured discover for a config-dependent cursor, a substream with a config-dependent parent, and a StateDelegatingStream; catalog-only streams can't be read

The 2 remaining build failures are imports in each connector's own components.py: source-bigcommerce (pendulum) and source-braze (DatetimeBasedCursor, which the CDK no longer exports).

Only source-github was compared against a configured discover. For the other 198 newly covered sources, the evidence is that they return a catalog.

Newly covered sources

Show/Hide Content
  • source-100ms
  • source-7shifts
  • source-acuity-scheduling
  • source-adobe-commerce-magento
  • source-aircall
  • source-algolia
  • source-alpaca-broker-api
  • source-amplitude
  • source-appcues
  • source-appfigures
  • source-apple-search-ads
  • source-ashby
  • source-assemblyai
  • source-auth0
  • source-aviationstack
  • source-awin-advertiser
  • source-basecamp
  • source-beamer
  • source-bitly
  • source-bluetally
  • source-boldsign
  • source-brevo
  • source-brex
  • source-buildkite
  • source-buzzsprout
  • source-callrail
  • source-capsule-crm
  • source-castor-edc
  • source-chameleon
  • source-chargebee
  • source-cimis
  • source-circa
  • source-circleci
  • source-clarif-ai
  • source-clockodo
  • source-close-com
  • source-codefresh
  • source-coingecko-coins
  • source-commission-junction
  • source-convertkit
  • source-criteo-marketing
  • source-cursor
  • source-datascope
  • source-delighted
  • source-ding-connect
  • source-dixa
  • source-docuseal
  • source-dolibarr
  • source-dropbox-sign
  • source-dust
  • source-dwolla
  • source-easypost
  • source-ebay-finance
  • source-ebay-fulfillment
  • source-elasticemail
  • source-eventbrite
  • source-exchange-rates
  • source-factorial
  • source-fastly
  • source-finage
  • source-flexport
  • source-float
  • source-freshchat
  • source-freshservice
  • source-front
  • source-giphy
  • source-github
  • source-gitlab
  • source-gmail
  • source-gologin
  • source-gong
  • source-google-tasks
  • source-gorgias
  • source-greenhouse
  • source-guru
  • source-harvest
  • source-height
  • source-help-scout
  • source-high-level
  • source-insightful
  • source-insightly
  • source-intercom
  • source-jira
  • source-jotform
  • source-judge-me-reviews
  • source-justcall
  • source-katana
  • source-klaus-api
  • source-klaviyo
  • source-less-annoying-crm
  • source-lever-hiring
  • source-linear
  • source-linkedin-pages
  • source-lob
  • source-mailchimp
  • source-mailersend
  • source-mantle
  • source-mendeley
  • source-missive
  • source-mixmax
  • source-mntn
  • source-monday
  • source-mux
  • source-nasa
  • source-navan
  • source-nebius-ai
  • source-newsdata-io
  • source-nexiopay
  • source-ninjaone-rmm
  • source-nytimes
  • source-oncehub
  • source-onesignal
  • source-open-exchange-rates
  • source-opsgenie
  • source-orb
  • source-outreach
  • source-paddle
  • source-pandadoc
  • source-pardot
  • source-partnerstack
  • source-paypal-transaction
  • source-paystack
  • source-pennylane
  • source-perigon
  • source-perk
  • source-phyllo
  • source-picqer
  • source-plaid
  • source-postmarkapp
  • source-prestashop
  • source-productboard
  • source-quickbooks
  • source-rd-station-marketing
  • source-reddit
  • source-reddit-ads
  • source-retailexpress-by-maropost
  • source-retently
  • source-revenuecat
  • source-revolut-merchant
  • source-rollbar
  • source-rootly
  • source-salesloft
  • source-segment
  • source-sendgrid
  • source-sendowl
  • source-senseforce
  • source-sharetribe
  • source-shiftbase
  • source-shippo
  • source-shipstation
  • source-shopwired
  • source-shortcut
  • source-shortio
  • source-shutterstock
  • source-signnow
  • source-slack
  • source-smartwaiver
  • source-solarwinds-service-desk
  • source-sparkpost
  • source-square
  • source-squarespace
  • source-statsig
  • source-strava
  • source-survicate
  • source-svix
  • source-tavus
  • source-teamwork
  • source-the-guardian-api
  • source-thrive-learning
  • source-ticktick
  • source-timely
  • source-trustpilot
  • source-tvmaze-schedule
  • source-typeform
  • source-uppromote
  • source-uservoice
  • source-veeqo
  • source-vercel
  • source-vwo
  • source-wasabi-stats-api
  • source-watchmode
  • source-wikipedia-pageviews
  • source-woocommerce
  • source-wordpress
  • source-workable
  • source-workflowmax
  • source-xero
  • source-yahoo-finance-price
  • source-yotpo
  • source-yousign
  • source-youtube-data
  • source-zapsign
  • source-zendesk-chat
  • source-zendesk-sunshine
  • source-zendesk-support
  • source-zendesk-talk
  • source-zoho-books
  • source-zoho-inventory

Link to Devin session: https://app.devin.ai/sessions/ae9d8c8aceea4199ac2609308e973916
Open in Devin Desktop: https://app.devin.ai/desktop/session/ae9d8c8aceea4199ac2609308e973916?variant=devin
Requested by: Aaron ("AJ") Steers (@aaronsteers)

Co-Authored-By: AJ Steers <aj@airbyte.io>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions

Copy link
Copy Markdown

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

Testing This CDK Version

You can test this version of the CDK using the following:

# Run the CLI from this branch:
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@devin/1792446479-catalog-only-discover#egg=airbyte-python-cdk[dev]' --help

# Update a connector to use the CDK from this branch ref:
cd airbyte-integrations/connectors/source-example
poe use-cdk-branch devin/1792446479-catalog-only-discover

PR Slash Commands

Airbyte Maintainers can execute the following slash commands on your PR:

  • /autofix - Fixes most formatting and linting issues
  • /poetry-lock - Updates poetry.lock file
  • /test - Runs connector tests with the updated CDK
  • /prerelease - Triggers a prerelease publish with default arguments
  • /poe build - Regenerate git-committed build artifacts, such as the pydantic models which are generated from the manifest JSON schema in YAML.
  • /poe <command> - Runs any poe command in the CDK environment
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

PyTest Results (Fast)

5 775 tests  +8   5 744 ✅ +8   12m 43s ⏱️ + 4m 57s
    1 suites ±0      31 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 296c1fc. ± Comparison against base commit 784a5f9.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

PyTest Results (Full)

5 778 tests  +8   5 747 ✅ +8   17m 16s ⏱️ +24s
    1 suites ±0      31 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 296c1fc. ± Comparison against base commit 784a5f9.

♻️ This comment has been updated with latest results.

Copilot AI 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.

🟡 Changes recommended

Missing config values in cursor-field templates can silently produce incorrect catalogs instead of configuration errors.

1 open issue
What changed in this PR

Extends config-free discovery with catalog-only streams, avoiding construction of credential-dependent runtime components.

Changes:

  • Routes eligible config-free discovery through catalog-only stream construction.
  • Shares schema loading and cursor-field resolution with full streams.
  • Adds catalog parity tests and a guard against reading catalog-only streams.
File Description
unit_tests/​sources/​declarative/​test_concurrent_declarative_source_config_free_discover.py Tests catalog parity and read prevention.
airbyte_cdk/​sources/​declarative/​parsers/​model_to_component_factory.py Adds catalog-only construction and shared metadata helpers.
airbyte_cdk/​sources/​declarative/​concurrent_declarative_source.py Routes eligible discovery to catalog-only streams.

Review effort: Balanced

devin-ai-integration Bot and others added 2 commits October 19, 2026 22:23
…onfig value

Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>

This branch has not been deployed

No deployments
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