Skip to content

feat: add airbyte-cdk CLI with support for: connector test, secrets fetch and --version #493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 102 commits into from
Apr 25, 2025

Conversation

aaronsteers
Copy link
Contributor

@aaronsteers aaronsteers commented Apr 18, 2025

Overview

This PR makes the CDK a true "developer kit" and not just a library.

Simple functions can be performed directly from the new airbyte-cdk CLI, starting with:

  • airbyte-cdk --help - Print usage info and exit.
  • airbyte-cdk --version - Print the CDK version and exit.
  • airbyte-cdk connector test - Test the connector using the new FAST Airbyte Standard Tests framework. (No stub file required, and connector type is autodetected from metadata.yaml.)
  • airbyte-cdk secrets fetch - Fetch the secrets for a given connector into the connector's secrets directory (e.g. source-s3/secrets for the S3 source.

(Each command group and command also support --help.)

CLI Screenshot: --help

image

Loom Demo

https://www.loom.com/share/970666990f564eed8dda8e089cfbe6df?sid=798c51df-73a5-44d6-b3be-6e9c64872931

Future Work (Not in Scope Here)

In a future iteration, I'm planning to add --docker-image support within connector test command. This would run all of the FAST Standard tests against the docker image, rather than using the local python environment. (This is mostly useful in CI to ensure the image is healthy, or for Java/Kotlin connectors.)

I also added stubs for manifest and image command groups, which I expect we may want to populate in the future with something like...:

How many CLI entrypoints would we have after this?

I think the goal is to have exactly 2 CLI entrypoints:

  1. source-declarative-manifest - this is literally how source-declarative-manifest is invoked as a connector and it lives in the CDK.
  2. airbyte-cdk - This is the new "dev tools" CLI - and we can put all manner of dev-related tools in here as needed. This should replace the more fragile and awkward python -m ....-based invocations. By structuring under command groups (secrets, manifest, connector, etc.), we can avoid needing multiple entrypoints for different purposes.

How is this invoked?

There are three invocation patterns:

  1. Stateless invocation (all connector types): pipx run airbyte-cdk ... or uvx airbyte-cdk .... This doesn't require a pre-install and it uses the latest version by default.
  2. Invocation from poetry. When working on a connector that has a poetry venv, you can invoke with poetry run airbyte-cdk .... This uses exactly the version of the CDK that you have in your dev environment, and it runs directly within your venv. When you bump the CDK version in your project, you also bump the CDK CLI version.
  3. Pre-installed locally. Similar to the stateless option but with slightly less typing. pipx install airbyte-cdk or uv tool install airbyte-cdk allows you to just invoke directly with no prefix: airbyte-cdk .... If you use this method, you just have to ensure you remember to upgrade occassionally.

Why choose airbyte-cdk as the name of the CLI entrypoint?

There are really two main reasons I arrived on using the airbyte-cdk name:

First, the name aligns exactly with the functions it delivers: these are the "connector developer kit" actions that are needed by developers during development.

Second, by aligning the name of the CLI with the name of the package, we get a much more concise stateless invocation when running with pipx or uvx.

When names don't match, you end up having to type both the package name and the CLI name like this (using --from or --spec):

uvx --from=airbyte-cdk airbyte-cdk --help
pipx run --spec=airbyte-cdk airbyte-cdk --help

But because the CLI name matches the package name, we can use this much more concise shorthand, where the package name and CLI name are one and the same:

uvx airbyte-cdk --help
pipx run airbyte-cdk --help

Summary by CodeRabbit

  • New Features
    • Introduced a command-line interface (CLI) for the Airbyte CDK with commands for connectors, manifests, images, and secrets management.
    • Added a command to run standard connector tests via the CLI.
    • Added a secrets fetch command to retrieve connector secrets from Google Secret Manager and store them locally.
  • Improvements
    • Enhanced test suite utilities for easier connector test setup and execution.
    • Improved handling and resolution of connector directories and names.
  • Documentation
    • Updated contributing guide with instructions for handling dependency analysis using Deptry.
  • Chores
    • Updated dependencies and scripts in project configuration.
    • Added .tmp to .gitignore to exclude temporary files.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
docs/CONTRIBUTING.md (1)

58-61: Minor grammar tweak for smoother reading

The phrase “Include an inline comment explaining why the ignore is needed.” sounds slightly awkward because “ignore” is being used as a noun. Would you consider re‑phrasing to “Include an inline comment explaining why the ignore rule is needed.” wdyt?

🧰 Tools
🪛 LanguageTool

[grammar] ~60-~60: The verb ‘ignore’ does not usually follow articles like ‘the’. Check that ‘ignore’ is spelled correctly; using ‘ignore’ as a noun may be non-standard.
Context: ...nclude an inline comment explaining why the ignore is needed. Example: ```toml [tool.dep...

(A_INFINITIVE)

airbyte_cdk/cli/airbyte_cdk/__init__.py (1)

55-60: Leverage click.version_option for a simpler --version flag

click already provides a convenient decorator (@click.version_option) that handles the --version flag (including -V, eager evaluation, etc.). Using it would remove the manual flag wiring and a handful of lines. Something like:

-@click.option(
-    "--version",
-    is_flag=True,
-    help="Show the version of the Airbyte CDK.",
-)
+@click.version_option(message="Airbyte CDK version: %(version)s")

The decorator could call print_version internally (or you can drop that indirection entirely). What do you think?

airbyte_cdk/cli/airbyte_cdk/_secrets.py (1)

105-113: Support default Google credentials for smoother UX?

Right now the command errors if GCP_GSM_CREDENTIALS is absent. Many GCP environments rely on the default credentials file (GOOGLE_APPLICATION_CREDENTIALS) or on workload identity. Would it be useful to fall back to secretmanager.SecretManagerServiceClient() without explicit credentials when GCP_GSM_CREDENTIALS isn’t set, and only raise if that also fails?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f025ba and 6fdf2c6.

⛔ Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • airbyte_cdk/cli/airbyte_cdk/__init__.py (1 hunks)
  • airbyte_cdk/cli/airbyte_cdk/_secrets.py (1 hunks)
  • docs/CONTRIBUTING.md (1 hunks)
  • pyproject.toml (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pyproject.toml
🧰 Additional context used
🧬 Code Graph Analysis (1)
airbyte_cdk/cli/airbyte_cdk/__init__.py (5)
airbyte_cdk/cli/airbyte_cdk/_connector.py (1)
  • connector_cli_group (92-94)
airbyte_cdk/cli/airbyte_cdk/_image.py (1)
  • image_cli_group (8-10)
airbyte_cdk/cli/airbyte_cdk/_manifest.py (1)
  • manifest_cli_group (14-18)
airbyte_cdk/cli/airbyte_cdk/_secrets.py (1)
  • secrets_cli_group (35-37)
airbyte_cdk/cli/airbyte_cdk/_version.py (1)
  • print_version (7-13)
🪛 LanguageTool
docs/CONTRIBUTING.md

[grammar] ~60-~60: The verb ‘ignore’ does not usually follow articles like ‘the’. Check that ‘ignore’ is spelled correctly; using ‘ignore’ as a noun may be non-standard.
Context: ...nclude an inline comment explaining why the ignore is needed. Example: ```toml [tool.dep...

(A_INFINITIVE)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: Check: 'source-pokeapi' (skip=false)
  • GitHub Check: Check: 'source-amplitude' (skip=false)
  • GitHub Check: Check: 'source-shopify' (skip=false)
  • GitHub Check: Check: 'source-hardcoded-records' (skip=false)
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: preview_docs
  • GitHub Check: Pytest (Fast)
  • GitHub Check: SDM Docker Image Build
  • GitHub Check: Analyze (python)
🔇 Additional comments (1)
airbyte_cdk/cli/airbyte_cdk/__init__.py (1)

70-76:

❌ Incorrect review comment

Sub‑command groups may not be valid click.Command objects

cli.add_command(connector_cli_group) (and the three siblings) assumes that each imported symbol is already a click.Command/Group. The snippet in _connector.py shows a plain function stub returning None, which would cause a runtime failure:

TypeError: Command is not a click command (got None)

Could you double‑check that the actual implementation decorates those callables with @click.group() (or returns a properly configured command) before registering them?


🏁 Script executed:

#!/bin/bash
# Locate where connector_cli_group is defined or imported
rg -n 'connector_cli_group' -n .

echo
# List all definitions of any *_cli_group to see if they’re decorated
rg -n 'def .*_cli_group' -n .

echo
# Search for @click.group decorators within the CLI package
rg -n '@click\.group' -n airbyte_cdk/cli/airbyte_cdk

Length of output: 1202


No Issue: CLI Groups Are Already Decorated
I’ve confirmed that each *_cli_group function is decorated with @click.group, so they return valid click.Group objects and can be safely registered via cli.add_command. wdyt?

• airbyte_cdk/cli/airbyte_cdk/_connector.py:91 – @click.group(name="connector")
• airbyte_cdk/cli/airbyte_cdk/_manifest.py:13 – @click.group(name="manifest")
• airbyte_cdk/cli/airbyte_cdk/_image.py:7 – @click.group(name="image")
• airbyte_cdk/cli/airbyte_cdk/_secrets.py:31 – @click.group

Likely an incorrect or invalid review comment.

@aaronsteers
Copy link
Contributor Author

aaronsteers commented Apr 19, 2025

/autofix

Auto-Fix Job Info

This job attempts to auto-fix any linting or formating issues. If any fixes are made,
those changes will be automatically committed and pushed back to the PR.

Note: This job can only be run by maintainers. On PRs from forks, this command requires
that the PR author has enabled the Allow edits from maintainers option.

PR auto-fix job started... Check job output.

🟦 Job completed successfully (no changes).

@aaronsteers
Copy link
Contributor Author

aaronsteers commented Apr 24, 2025

/poetry-lock

Poetry-Lock Job Info

This job attempts to re-lock dependencies using poetry lock command. If any changes
are made, those changes will be automatically committed and pushed back to the PR.

Note: This job can only be run by maintainers. On PRs from forks, this command requires
that the PR author has enabled the Allow edits from maintainers option.

poetry lock job started... Check job output.

poetry lock applied successfully.

Copy link
Contributor

@aldogonzalez8 aldogonzalez8 left a comment

Choose a reason for hiding this comment

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

APPROVED

@aaronsteers
Copy link
Contributor Author

aaronsteers commented Apr 25, 2025

/poetry-lock

Poetry-Lock Job Info

This job attempts to re-lock dependencies using poetry lock command. If any changes
are made, those changes will be automatically committed and pushed back to the PR.

Note: This job can only be run by maintainers. On PRs from forks, this command requires
that the PR author has enabled the Allow edits from maintainers option.

poetry lock job started... Check job output.

poetry lock applied successfully.

@aaronsteers aaronsteers enabled auto-merge (squash) April 25, 2025 05:02
@aaronsteers aaronsteers merged commit 3f2ba17 into main Apr 25, 2025
26 of 27 checks passed
@aaronsteers aaronsteers deleted the aj/feat/add-standard-tests-cli branch April 25, 2025 05:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants