Skip to content

Commit 5873c39

Browse files
authored
Merge branch 'main' into lmossman/another-reordering
2 parents 842ccba + 88f8256 commit 5873c39

28 files changed

+783
-190
lines changed

.github/pr-welcome-community.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## 👋 Welcome to the Airbyte Python CDK!
2+
3+
Thank you for your contribution from **{{ .repo_name }}**! We're excited to have you in the Airbyte community.
4+
5+
### Testing This CDK Version
6+
7+
You can test this version of the CDK using the following:
8+
9+
```bash
10+
# Run the CLI from this branch:
11+
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@{{ .branch_name }}#egg=airbyte-python-cdk[dev]' --help
12+
13+
# Update a connector to use the CDK from this branch ref:
14+
cd airbyte-integrations/connectors/source-example
15+
poe use-cdk-branch {{ .branch_name }}
16+
```
17+
18+
### Helpful Resources
19+
20+
- [Contributing Guidelines](https://docs.airbyte.com/contributing-to-airbyte/)
21+
- [CDK API Reference](https://airbytehq.github.io/airbyte-python-cdk/)
22+
23+
### PR Slash Commands
24+
25+
As needed or by request, Airbyte Maintainers can execute the following slash commands on your PR:
26+
27+
- `/autofix` - Fixes most formatting and linting issues
28+
- `/poetry-lock` - Updates poetry.lock file
29+
- `/test` - Runs connector tests with the updated CDK
30+
31+
If you have any questions, feel free to ask in the PR comments or join our [Slack community](https://airbytehq.slack.com/).
32+

.github/pr-welcome-internal.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
## 👋 Greetings, Airbyte Team Member!
2+
3+
Here are some helpful tips and reminders for your convenience.
4+
5+
### Testing This CDK Version
6+
7+
You can test this version of the CDK using the following:
8+
9+
```bash
10+
# Run the CLI from this branch:
11+
uvx 'git+https://github.com/airbytehq/airbyte-python-cdk.git@{{ .branch_name }}#egg=airbyte-python-cdk[dev]' --help
12+
13+
# Update a connector to use the CDK from this branch ref:
14+
cd airbyte-integrations/connectors/source-example
15+
poe use-cdk-branch {{ .branch_name }}
16+
```
17+
18+
### Helpful Resources
19+
20+
- [CDK API Reference](https://airbytehq.github.io/airbyte-python-cdk/)
21+
22+
### PR Slash Commands
23+
24+
Airbyte Maintainers can execute the following slash commands on your PR:
25+
26+
- `/autofix` - Fixes most formatting and linting issues
27+
- `/poetry-lock` - Updates poetry.lock file
28+
- `/test` - Runs connector tests with the updated CDK
29+
- `/poe <command>` - Runs any poe command in the CDK environment
30+
31+
[📝 _Edit this welcome message._](https://github.com/airbytehq/airbyte-python-cdk/blob/main/.github/pr-welcome-internal.md)

.github/workflows/connector-tests.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ jobs:
7575
- connector: source-google-drive
7676
cdk_extra: file-based
7777
- connector: destination-motherduck
78-
cdk_extra: sql
79-
- connector: source-amplitude
80-
cdk_extra: n/a
78+
# For now, we mark as 'n/a' to always test this connector
79+
cdk_extra: n/a # change to 'sql' to test less often
80+
# source-amplitude failing for unrelated issue "date too far back"
81+
# e.g. https://github.com/airbytehq/airbyte-python-cdk/actions/runs/16053716569/job/45302638848?pr=639
82+
# - connector: source-amplitude
83+
# cdk_extra: n/a
8184
- connector: source-intercom
8285
cdk_extra: n/a
8386
- connector: source-pokeapi

.github/workflows/python_lint.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- name: Install dependencies
2727
run: poetry install --all-extras
2828

29-
# Job-specifc step(s):
29+
# Job-specific step(s):
3030
- name: Run lint check
3131
run: poetry run ruff check .
3232

@@ -49,9 +49,9 @@ jobs:
4949
- name: Install dependencies
5050
run: poetry install --all-extras
5151

52-
# Job-specifc step(s):
52+
# Job-specific step(s):
5353
- name: Check code format
54-
run: poetry run ruff format --check .
54+
run: poetry run ruff format --diff .
5555

5656
mypy-check:
5757
name: MyPy Check
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Community PR Welcome Message
2+
3+
# This workflow automatically adds a welcome message to PRs from community contributors (forks)
4+
# It includes CDK usage instructions and other helpful resources for testing changes
5+
#
6+
# MANUAL TESTING INSTRUCTIONS:
7+
# To manually test this workflow, temporarily uncomment the "synchronize" event type as a workflow trigger.
8+
# Then the workflow will run for all new commits.
9+
#
10+
# Before merging, remember to again comment-out the "synchronize" clause and uncomment the `if:` condition.
11+
12+
on:
13+
pull_request:
14+
types:
15+
- opened
16+
- reopened
17+
# Toggle this line, uncommenting for testing:
18+
# - synchronize
19+
20+
jobs:
21+
welcome-contributor:
22+
name: PR Welcome Message
23+
permissions:
24+
contents: read
25+
issues: write
26+
pull-requests: write
27+
runs-on: ubuntu-24.04
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
32+
- name: Render template
33+
id: template
34+
uses: chuhlomin/[email protected]
35+
with:
36+
# Use a different template for internal vs forks (community)
37+
template: ${{ github.event.pull_request.head.repo.fork == true && '.github/pr-welcome-community.md' || '.github/pr-welcome-internal.md' }}
38+
vars: |
39+
repo_name: ${{ github.event.pull_request.head.repo.full_name }}
40+
branch_name: ${{ github.event.pull_request.head.ref }}
41+
42+
- name: Create comment
43+
uses: peter-evans/create-or-update-comment@v4
44+
with:
45+
issue-number: ${{ github.event.pull_request.number }}
46+
body: ${{ steps.template.outputs.result }}

airbyte_cdk/cli/airbyte_cdk/_connector.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767

6868
TEST_FILE_TEMPLATE = '''
6969
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
70-
"""FAST Airbyte Standard Tests for the {connector_name} source."""
70+
"""FAST Airbyte Standard Tests for the {connector_name} connector."""
7171
7272
#from airbyte_cdk.test.standard_tests import {base_class_name}
7373
from airbyte_cdk.test.standard_tests.util import create_connector_test_suite
@@ -81,11 +81,13 @@
8181
connector_directory=Path(),
8282
)
8383
84+
# Uncomment the following lines to create a custom test suite class:
85+
#
8486
# class TestSuite({base_class_name}):
85-
# """Test suite for the {connector_name} source.
86-
87-
# This class inherits from SourceTestSuiteBase and implements all of the tests in the suite.
88-
87+
# """Test suite for the `{connector_name}` connector.
88+
#
89+
# This class inherits from `{base_class_name}` and implements all of the tests in the suite.
90+
#
8991
# As long as the class name starts with "Test", pytest will automatically discover and run the
9092
# tests in this class.
9193
# """

airbyte_cdk/sources/declarative/declarative_component_schema.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,9 +2043,15 @@ definitions:
20432043
- "$ref": "#/definitions/NoAuth"
20442044
- "$ref": "#/definitions/LegacySessionTokenAuthenticator"
20452045
fetch_properties_from_endpoint:
2046+
deprecated: true
2047+
deprecation_message: "Use `query_properties` field instead."
20462048
title: Fetch Properties from Endpoint
20472049
description: Allows for retrieving a dynamic set of properties from an API endpoint which can be injected into outbound request using the stream_partition.extra_fields.
20482050
"$ref": "#/definitions/PropertiesFromEndpoint"
2051+
query_properties:
2052+
title: Query Properties
2053+
description: For APIs that require explicit specification of the properties to query for, this component will take a static or dynamic set of properties (which can be optionally split into chunks) and allow them to be injected into an outbound request by accessing stream_partition.extra_fields.
2054+
"$ref": "#/definitions/QueryProperties"
20492055
request_parameters:
20502056
title: Query Parameters
20512057
description: Specifies the query parameters that should be set on an outgoing HTTP request given the inputs.
@@ -4235,6 +4241,11 @@ definitions:
42354241
- "$ref": "#/definitions/HttpComponentsResolver"
42364242
- "$ref": "#/definitions/ConfigComponentsResolver"
42374243
- "$ref": "#/definitions/ParametrizedComponentsResolver"
4244+
use_parent_parameters:
4245+
title: Use Parent Parameters
4246+
description: Whether or not to prioritize parent parameters over component parameters when constructing dynamic streams. Defaults to true for backward compatibility.
4247+
type: boolean
4248+
default: true
42384249
required:
42394250
- type
42404251
- stream_template

airbyte_cdk/sources/declarative/interpolation/macros.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import builtins
66
import datetime
7+
import re
78
import typing
89
from typing import Optional, Union
910
from urllib.parse import quote_plus
@@ -194,6 +195,18 @@ def sanitize_url(value: str) -> str:
194195
return sanitization_strategy(value)
195196

196197

198+
def camel_case_to_snake_case(value: str) -> str:
199+
"""
200+
Converts CamelCase strings to snake_case format
201+
202+
Usage:
203+
`"{{ camel_case_to_snake_case('CamelCase') }}"`
204+
:param value: string to convert from CamelCase to snake_case
205+
:return: snake_case formatted string
206+
"""
207+
return re.sub(r"(?<!^)(?=[A-Z])", "_", value).lower()
208+
209+
197210
_macros_list = [
198211
now_utc,
199212
today_utc,
@@ -206,5 +219,6 @@ def sanitize_url(value: str) -> str:
206219
today_with_timezone,
207220
str_to_datetime,
208221
sanitize_url,
222+
camel_case_to_snake_case,
209223
]
210224
macros = {f.__name__: f for f in _macros_list}

airbyte_cdk/sources/declarative/manifest_declarative_source.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,9 +553,13 @@ def _dynamic_stream_configs(
553553
for dynamic_stream in components_resolver.resolve_components(
554554
stream_template_config=stream_template_config
555555
):
556+
# Get the use_parent_parameters configuration from the dynamic definition
557+
# Default to True for backward compatibility, since connectors were already using it by default when this param was added
558+
use_parent_parameters = dynamic_definition.get("use_parent_parameters", True)
559+
556560
dynamic_stream = {
557561
**ManifestComponentTransformer().propagate_types_and_parameters(
558-
"", dynamic_stream, {}, use_parent_parameters=True
562+
"", dynamic_stream, {}, use_parent_parameters=use_parent_parameters
559563
)
560564
}
561565

airbyte_cdk/sources/declarative/models/declarative_component_schema.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Copyright (c) 2025 Airbyte, Inc., all rights reserved.
2+
13
# generated by datamodel-codegen:
24
# filename: declarative_component_schema.yaml
35

@@ -2541,9 +2543,16 @@ class HttpRequester(BaseModelWithDeprecations):
25412543
)
25422544
fetch_properties_from_endpoint: Optional[PropertiesFromEndpoint] = Field(
25432545
None,
2546+
deprecated=True,
2547+
deprecation_message="Use `query_properties` field instead.",
25442548
description="Allows for retrieving a dynamic set of properties from an API endpoint which can be injected into outbound request using the stream_partition.extra_fields.",
25452549
title="Fetch Properties from Endpoint",
25462550
)
2551+
query_properties: Optional[QueryProperties] = Field(
2552+
None,
2553+
description="For APIs that require explicit specification of the properties to query for, this component will take a static or dynamic set of properties (which can be optionally split into chunks) and allow them to be injected into an outbound request by accessing stream_partition.extra_fields.",
2554+
title="Query Properties",
2555+
)
25472556
request_parameters: Optional[Union[Dict[str, Union[str, QueryProperties]], str]] = Field(
25482557
None,
25492558
description="Specifies the query parameters that should be set on an outgoing HTTP request given the inputs.",
@@ -2958,6 +2967,11 @@ class DynamicDeclarativeStream(BaseModel):
29582967
description="Component resolve and populates stream templates with components values.",
29592968
title="Components Resolver",
29602969
)
2970+
use_parent_parameters: Optional[bool] = Field(
2971+
True,
2972+
description="Whether or not to prioritize parent parameters over component parameters when constructing dynamic streams. Defaults to true for backward compatibility.",
2973+
title="Use Parent Parameters",
2974+
)
29612975

29622976

29632977
ComplexFieldType.update_forward_refs()

0 commit comments

Comments
 (0)