Skip to content

Commit f18ce99

Browse files
feat(cdk): add examples and improve descriptions in YAML schema
- Add GraphQL query examples for RequestBodyGraphQlQuery - Enhance CustomIncrementalSync cursor_field with examples and title - Fix stream name example format (string instead of array) - Improve CursorPagination descriptions and add varied examples - Enhance ApiKeyAuthenticator with more header examples and better descriptions - Add realistic interpolation examples using {{ config['field'] }} syntax - Focus on complex components where user input is not obvious Co-Authored-By: AJ Steers <[email protected]>
1 parent a88adca commit f18ce99

File tree

2 files changed

+129
-29
lines changed

2 files changed

+129
-29
lines changed

airbyte_cdk/sources/declarative/declarative_component_schema.yaml

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -150,23 +150,30 @@ definitions:
150150
enum: [ApiKeyAuthenticator]
151151
api_token:
152152
title: API Key
153-
description: The API key to inject in the request. Fill it in the user inputs.
153+
description: The API key token that will be injected into requests for authentication. This should reference a configuration field that contains the user's API key. Can include formatting like 'Bearer' or 'Token' prefixes.
154154
type: string
155155
interpolation_context:
156156
- config
157157
examples:
158158
- "{{ config['api_key'] }}"
159159
- "Token token={{ config['api_key'] }}"
160+
- "Bearer {{ config['access_token'] }}"
161+
- "{{ config['auth_token'] }}"
162+
- "{{ config['secret_key'] }}"
160163
header:
161164
title: Header Name
162-
description: The name of the HTTP header that will be set to the API key. This setting is deprecated, use inject_into instead. Header and inject_into can not be defined at the same time.
165+
description: The name of the HTTP header where the API key will be injected. This setting is deprecated, use inject_into instead. Common headers include 'Authorization', 'X-API-Key', or custom headers specific to the API. Header and inject_into cannot be defined at the same time.
163166
type: string
164167
interpolation_context:
165168
- config
166169
examples:
167170
- Authorization
168171
- Api-Token
169172
- X-Auth-Token
173+
- X-API-Key
174+
- X-RapidAPI-Key
175+
- apikey
176+
- token
170177
inject_into:
171178
title: Inject API Key Into Outgoing HTTP Request
172179
description: Configure how the API Key will be sent in requests to the source API. Either inject_into or header has to be defined.
@@ -496,7 +503,7 @@ definitions:
496503
enum: [CursorPagination]
497504
cursor_value:
498505
title: Cursor Value
499-
description: Value of the cursor defining the next page to fetch.
506+
description: Template string for the cursor value to be used in the next request. This should reference a field from the API response that indicates the next page position.
500507
type: string
501508
interpolation_context:
502509
- config
@@ -508,12 +515,20 @@ definitions:
508515
- "{{ headers.link.next.cursor }}"
509516
- "{{ last_record['key'] }}"
510517
- "{{ response['nextPage'] }}"
518+
- "{{ response.next_cursor }}"
519+
- "{{ last_record['id'] }}"
520+
- "{{ headers['x-next-page'] }}"
521+
- "{{ response.pagination.next_token }}"
511522
page_size:
512523
title: Page Size
513-
description: The number of records to include in each pages.
524+
description: The number of records to include in each page. This value will be used with cursor-based pagination to control the amount of data returned per request. Choose a value that balances API rate limits with sync performance.
514525
type: integer
515526
examples:
527+
- 10
528+
- 50
516529
- 100
530+
- 500
531+
- 1000
517532
stop_condition:
518533
title: Stop Condition
519534
description: Template string evaluating when to stop paginating.
@@ -614,8 +629,15 @@ definitions:
614629
examples:
615630
- "source_railz.components.MyCustomIncrementalSync"
616631
cursor_field:
617-
description: The location of the value on a record that will be used as a bookmark during sync.
632+
title: Cursor Field
633+
description: The location of the value on a record that will be used as a bookmark during sync. This field should contain datetime values that increase over time to enable incremental syncing. The field must be at the top level of the record.
618634
type: string
635+
examples:
636+
- "updated_at"
637+
- "created_at"
638+
- "last_modified"
639+
- "timestamp"
640+
- "{{ config['cursor_field'] }}"
619641
$parameters:
620642
type: object
621643
additionalProperties: true
@@ -1496,11 +1518,16 @@ definitions:
14961518
enum: [DeclarativeStream]
14971519
name:
14981520
title: Name
1499-
description: The stream name.
1521+
description: The name of the stream as it will appear in the connector. This should be descriptive and match the data being synced (e.g., 'users', 'orders', 'transactions'). Use lowercase with underscores for consistency.
15001522
type: string
15011523
default: ""
1502-
example:
1503-
- "Users"
1524+
examples:
1525+
- "users"
1526+
- "orders"
1527+
- "transactions"
1528+
- "events"
1529+
- "user_profiles"
1530+
- "order_items"
15041531
retriever:
15051532
title: Retriever
15061533
description: Component used to coordinate how records are extracted across stream slices and request pages.
@@ -3135,7 +3162,7 @@ definitions:
31353162
enum: [OffsetIncrement]
31363163
page_size:
31373164
title: Limit
3138-
description: The number of records to include in each pages.
3165+
description: The number of records to include in each page. This value will be used to increment the offset for subsequent requests. Choose a value that balances API rate limits with sync performance.
31393166
anyOf:
31403167
- type: integer
31413168
title: Number of Records
@@ -3145,7 +3172,11 @@ definitions:
31453172
- config
31463173
- response
31473174
examples:
3175+
- 10
3176+
- 50
31483177
- 100
3178+
- 500
3179+
- 1000
31493180
- "{{ config['page_size'] }}"
31503181
inject_on_first_request:
31513182
title: Inject Offset on First Request
@@ -3167,7 +3198,7 @@ definitions:
31673198
enum: [PageIncrement]
31683199
page_size:
31693200
title: Page Size
3170-
description: The number of records to include in each pages.
3201+
description: The number of records to include in each page. This value will be used to increment the page number for subsequent requests. Choose a value that balances API rate limits with sync performance.
31713202
interpolation_context:
31723203
- config
31733204
anyOf:
@@ -3176,7 +3207,11 @@ definitions:
31763207
- type: string
31773208
title: Interpolated Value
31783209
examples:
3210+
- 10
3211+
- 50
31793212
- 100
3213+
- 500
3214+
- 1000
31803215
- "100"
31813216
- "{{ config['page_size'] }}"
31823217
start_from_page:
@@ -3621,11 +3656,16 @@ definitions:
36213656
enum: [StateDelegatingStream]
36223657
name:
36233658
title: Name
3624-
description: The stream name.
3659+
description: The name of the stream as it will appear in the connector. This should be descriptive and match the data being synced (e.g., 'users', 'orders', 'transactions'). Use lowercase with underscores for consistency.
36253660
type: string
36263661
default: ""
3627-
example:
3628-
- "Users"
3662+
examples:
3663+
- "users"
3664+
- "orders"
3665+
- "transactions"
3666+
- "events"
3667+
- "user_profiles"
3668+
- "order_items"
36293669
full_refresh_stream:
36303670
title: Full Refresh Stream
36313671
description: Component used to coordinate how records are extracted across stream slices and request pages when the state is empty or not provided.
@@ -4417,8 +4457,13 @@ definitions:
44174457
properties:
44184458
query:
44194459
type: string
4420-
description: The GraphQL query to be executed
4460+
description: The GraphQL query to be executed. This should be a valid GraphQL query string that will be sent in the request body.
44214461
default: "query {\n \n}"
4462+
examples:
4463+
- "query { users { id name email } }"
4464+
- "query GetUser($id: ID!) { user(id: $id) { name email } }"
4465+
- "{ viewer { login repositories(first: 10) { nodes { name } } } }"
4466+
- "mutation CreateUser($input: UserInput!) { createUser(input: $input) { id } }"
44224467
additionalProperties: true
44234468
DpathValidator:
44244469
title: Dpath Validator

airbyte_cdk/sources/declarative/models/declarative_component_schema.py

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,18 +104,22 @@ class CursorPagination(BaseModel):
104104
type: Literal["CursorPagination"]
105105
cursor_value: str = Field(
106106
...,
107-
description="Value of the cursor defining the next page to fetch.",
107+
description="Template string for the cursor value to be used in the next request. This should reference a field from the API response that indicates the next page position.",
108108
examples=[
109109
"{{ headers.link.next.cursor }}",
110110
"{{ last_record['key'] }}",
111111
"{{ response['nextPage'] }}",
112+
"{{ response.next_cursor }}",
113+
"{{ last_record['id'] }}",
114+
"{{ headers['x-next-page'] }}",
115+
"{{ response.pagination.next_token }}",
112116
],
113117
title="Cursor Value",
114118
)
115119
page_size: Optional[int] = Field(
116120
None,
117-
description="The number of records to include in each pages.",
118-
examples=[100],
121+
description="The number of records to include in each page. This value will be used with cursor-based pagination to control the amount of data returned per request. Choose a value that balances API rate limits with sync performance.",
122+
examples=[10, 50, 100, 500, 1000],
119123
title="Page Size",
120124
)
121125
stop_condition: Optional[str] = Field(
@@ -185,7 +189,15 @@ class Config:
185189
)
186190
cursor_field: str = Field(
187191
...,
188-
description="The location of the value on a record that will be used as a bookmark during sync.",
192+
description="The location of the value on a record that will be used as a bookmark during sync. This field should contain datetime values that increase over time to enable incremental syncing. The field must be at the top level of the record.",
193+
examples=[
194+
"updated_at",
195+
"created_at",
196+
"last_modified",
197+
"timestamp",
198+
"{{ config['cursor_field'] }}",
199+
],
200+
title="Cursor Field",
189201
)
190202
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
191203

@@ -1201,8 +1213,8 @@ class OffsetIncrement(BaseModel):
12011213
type: Literal["OffsetIncrement"]
12021214
page_size: Optional[Union[int, str]] = Field(
12031215
None,
1204-
description="The number of records to include in each pages.",
1205-
examples=[100, "{{ config['page_size'] }}"],
1216+
description="The number of records to include in each page. This value will be used to increment the offset for subsequent requests. Choose a value that balances API rate limits with sync performance.",
1217+
examples=[10, 50, 100, 500, 1000, "{{ config['page_size'] }}"],
12061218
title="Limit",
12071219
)
12081220
inject_on_first_request: Optional[bool] = Field(
@@ -1217,8 +1229,8 @@ class PageIncrement(BaseModel):
12171229
type: Literal["PageIncrement"]
12181230
page_size: Optional[Union[int, str]] = Field(
12191231
None,
1220-
description="The number of records to include in each pages.",
1221-
examples=[100, "100", "{{ config['page_size'] }}"],
1232+
description="The number of records to include in each page. This value will be used to increment the page number for subsequent requests. Choose a value that balances API rate limits with sync performance.",
1233+
examples=[10, 50, 100, 500, 1000, "100", "{{ config['page_size'] }}"],
12221234
title="Page Size",
12231235
)
12241236
start_from_page: Optional[int] = Field(
@@ -1579,7 +1591,16 @@ class RequestBodyGraphQlQuery(BaseModel):
15791591
class Config:
15801592
extra = Extra.allow
15811593

1582-
query: str = Field(..., description="The GraphQL query to be executed")
1594+
query: str = Field(
1595+
...,
1596+
description="The GraphQL query to be executed. This should be a valid GraphQL query string that will be sent in the request body.",
1597+
examples=[
1598+
"query { users { id name email } }",
1599+
"query GetUser($id: ID!) { user(id: $id) { name email } }",
1600+
"{ viewer { login repositories(first: 10) { nodes { name } } } }",
1601+
"mutation CreateUser($input: UserInput!) { createUser(input: $input) { id } }",
1602+
],
1603+
)
15831604

15841605

15851606
class ValidateAdheresToSchema(BaseModel):
@@ -1732,14 +1753,28 @@ class ApiKeyAuthenticator(BaseModel):
17321753
type: Literal["ApiKeyAuthenticator"]
17331754
api_token: Optional[str] = Field(
17341755
None,
1735-
description="The API key to inject in the request. Fill it in the user inputs.",
1736-
examples=["{{ config['api_key'] }}", "Token token={{ config['api_key'] }}"],
1756+
description="The API key token that will be injected into requests for authentication. This should reference a configuration field that contains the user's API key. Can include formatting like 'Bearer' or 'Token' prefixes.",
1757+
examples=[
1758+
"{{ config['api_key'] }}",
1759+
"Token token={{ config['api_key'] }}",
1760+
"Bearer {{ config['access_token'] }}",
1761+
"{{ config['auth_token'] }}",
1762+
"{{ config['secret_key'] }}",
1763+
],
17371764
title="API Key",
17381765
)
17391766
header: Optional[str] = Field(
17401767
None,
1741-
description="The name of the HTTP header that will be set to the API key. This setting is deprecated, use inject_into instead. Header and inject_into can not be defined at the same time.",
1742-
examples=["Authorization", "Api-Token", "X-Auth-Token"],
1768+
description="The name of the HTTP header where the API key will be injected. This setting is deprecated, use inject_into instead. Common headers include 'Authorization', 'X-API-Key', or custom headers specific to the API. Header and inject_into cannot be defined at the same time.",
1769+
examples=[
1770+
"Authorization",
1771+
"Api-Token",
1772+
"X-Auth-Token",
1773+
"X-API-Key",
1774+
"X-RapidAPI-Key",
1775+
"apikey",
1776+
"token",
1777+
],
17431778
title="Header Name",
17441779
)
17451780
inject_into: Optional[RequestOption] = Field(
@@ -2441,7 +2476,17 @@ class Config:
24412476

24422477
type: Literal["DeclarativeStream"]
24432478
name: Optional[str] = Field(
2444-
"", description="The stream name.", example=["Users"], title="Name"
2479+
"",
2480+
description="The name of the stream as it will appear in the connector. This should be descriptive and match the data being synced (e.g., 'users', 'orders', 'transactions'). Use lowercase with underscores for consistency.",
2481+
examples=[
2482+
"users",
2483+
"orders",
2484+
"transactions",
2485+
"events",
2486+
"user_profiles",
2487+
"order_items",
2488+
],
2489+
title="Name",
24452490
)
24462491
retriever: Union[SimpleRetriever, AsyncRetriever, CustomRetriever] = Field(
24472492
...,
@@ -2808,7 +2853,17 @@ class QueryProperties(BaseModel):
28082853
class StateDelegatingStream(BaseModel):
28092854
type: Literal["StateDelegatingStream"]
28102855
name: str = Field(
2811-
..., description="The stream name.", example=["Users"], title="Name"
2856+
...,
2857+
description="The name of the stream as it will appear in the connector. This should be descriptive and match the data being synced (e.g., 'users', 'orders', 'transactions'). Use lowercase with underscores for consistency.",
2858+
examples=[
2859+
"users",
2860+
"orders",
2861+
"transactions",
2862+
"events",
2863+
"user_profiles",
2864+
"order_items",
2865+
],
2866+
title="Name",
28122867
)
28132868
full_refresh_stream: DeclarativeStream = Field(
28142869
...,

0 commit comments

Comments
 (0)