airbyte-cdk 6.9.1.dev2__py3-none-any.whl → 6.9.1rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airbyte_cdk/sources/declarative/concurrent_declarative_source.py +25 -31
- airbyte_cdk/sources/declarative/datetime/datetime_parser.py +4 -4
- airbyte_cdk/sources/declarative/declarative_component_schema.yaml +100 -2
- airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +1 -1
- airbyte_cdk/sources/declarative/manifest_declarative_source.py +53 -2
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py +95 -2
- airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +6 -0
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +95 -21
- airbyte_cdk/sources/declarative/partition_routers/__init__.py +2 -1
- airbyte_cdk/sources/declarative/resolvers/__init__.py +13 -0
- airbyte_cdk/sources/declarative/resolvers/components_resolver.py +55 -0
- airbyte_cdk/sources/declarative/resolvers/http_components_resolver.py +106 -0
- airbyte_cdk/sources/streams/concurrent/state_converters/datetime_stream_state_converter.py +2 -2
- airbyte_cdk-6.9.1rc2.dist-info/METADATA +108 -0
- {airbyte_cdk-6.9.1.dev2.dist-info → airbyte_cdk-6.9.1rc2.dist-info}/RECORD +18 -16
- airbyte_cdk/test/utils/manifest_only_fixtures.py +0 -79
- airbyte_cdk-6.9.1.dev2.dist-info/METADATA +0 -306
- {airbyte_cdk-6.9.1.dev2.dist-info → airbyte_cdk-6.9.1rc2.dist-info}/LICENSE.txt +0 -0
- {airbyte_cdk-6.9.1.dev2.dist-info → airbyte_cdk-6.9.1rc2.dist-info}/WHEEL +0 -0
- {airbyte_cdk-6.9.1.dev2.dist-info → airbyte_cdk-6.9.1rc2.dist-info}/entry_points.txt +0 -0
@@ -86,23 +86,10 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
|
|
86
86
|
component_factory=component_factory,
|
87
87
|
)
|
88
88
|
|
89
|
+
# todo: We could remove state from initialization. Now that streams are grouped during the read(), a source
|
90
|
+
# no longer needs to store the original incoming state. But maybe there's an edge case?
|
89
91
|
self._state = state
|
90
92
|
|
91
|
-
self._concurrent_streams: Optional[List[AbstractStream]]
|
92
|
-
self._synchronous_streams: Optional[List[Stream]]
|
93
|
-
|
94
|
-
# If the connector command was SPEC, there is no incoming config, and we cannot instantiate streams because
|
95
|
-
# they might depend on it. Ideally we want to have a static method on this class to get the spec without
|
96
|
-
# any other arguments, but the existing entrypoint.py isn't designed to support this. Just noting this
|
97
|
-
# for our future improvements to the CDK.
|
98
|
-
if config:
|
99
|
-
self._concurrent_streams, self._synchronous_streams = self._group_streams(
|
100
|
-
config=config or {}
|
101
|
-
)
|
102
|
-
else:
|
103
|
-
self._concurrent_streams = None
|
104
|
-
self._synchronous_streams = None
|
105
|
-
|
106
93
|
concurrency_level_from_manifest = self._source_config.get("concurrency_level")
|
107
94
|
if concurrency_level_from_manifest:
|
108
95
|
concurrency_level_component = self._constructor.create_component(
|
@@ -136,17 +123,20 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
|
|
136
123
|
logger: logging.Logger,
|
137
124
|
config: Mapping[str, Any],
|
138
125
|
catalog: ConfiguredAirbyteCatalog,
|
139
|
-
state: Optional[
|
126
|
+
state: Optional[List[AirbyteStateMessage]] = None,
|
140
127
|
) -> Iterator[AirbyteMessage]:
|
141
|
-
|
142
|
-
|
143
|
-
|
128
|
+
concurrent_streams, _ = self._group_streams(config=config)
|
129
|
+
|
130
|
+
# ConcurrentReadProcessor pops streams that are finished being read so before syncing, the names of
|
131
|
+
# the concurrent streams must be saved so that they can be removed from the catalog before starting
|
132
|
+
# synchronous streams
|
133
|
+
if len(concurrent_streams) > 0:
|
144
134
|
concurrent_stream_names = set(
|
145
|
-
[concurrent_stream.name for concurrent_stream in
|
135
|
+
[concurrent_stream.name for concurrent_stream in concurrent_streams]
|
146
136
|
)
|
147
137
|
|
148
138
|
selected_concurrent_streams = self._select_streams(
|
149
|
-
streams=
|
139
|
+
streams=concurrent_streams, configured_catalog=catalog
|
150
140
|
)
|
151
141
|
# It would appear that passing in an empty set of streams causes an infinite loop in ConcurrentReadProcessor.
|
152
142
|
# This is also evident in concurrent_source_adapter.py so I'll leave this out of scope to fix for now
|
@@ -165,8 +155,7 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
|
|
165
155
|
yield from super().read(logger, config, filtered_catalog, state)
|
166
156
|
|
167
157
|
def discover(self, logger: logging.Logger, config: Mapping[str, Any]) -> AirbyteCatalog:
|
168
|
-
concurrent_streams = self.
|
169
|
-
synchronous_streams = self._synchronous_streams or []
|
158
|
+
concurrent_streams, synchronous_streams = self._group_streams(config=config)
|
170
159
|
return AirbyteCatalog(
|
171
160
|
streams=[
|
172
161
|
stream.as_airbyte_stream() for stream in concurrent_streams + synchronous_streams
|
@@ -192,9 +181,13 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
|
|
192
181
|
|
193
182
|
state_manager = ConnectorStateManager(state=self._state) # type: ignore # state is always in the form of List[AirbyteStateMessage]. The ConnectorStateManager should use generics, but this can be done later
|
194
183
|
|
195
|
-
|
196
|
-
|
197
|
-
|
184
|
+
# Combine streams and dynamic_streams. Note: both cannot be empty at the same time,
|
185
|
+
# and this is validated during the initialization of the source.
|
186
|
+
streams = self._stream_configs(self._source_config) + self._dynamic_stream_configs(
|
187
|
+
self._source_config, config
|
188
|
+
)
|
189
|
+
|
190
|
+
name_to_stream_mapping = {stream["name"]: stream for stream in streams}
|
198
191
|
|
199
192
|
for declarative_stream in self.streams(config=config):
|
200
193
|
# Some low-code sources use a combination of DeclarativeStream and regular Python streams. We can't inspect
|
@@ -202,7 +195,7 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
|
|
202
195
|
# so we need to treat them as synchronous
|
203
196
|
if (
|
204
197
|
isinstance(declarative_stream, DeclarativeStream)
|
205
|
-
and name_to_stream_mapping[declarative_stream.name]
|
198
|
+
and name_to_stream_mapping[declarative_stream.name]["retriever"]["type"]
|
206
199
|
== "SimpleRetriever"
|
207
200
|
):
|
208
201
|
incremental_sync_component_definition = name_to_stream_mapping[
|
@@ -211,7 +204,7 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
|
|
211
204
|
|
212
205
|
partition_router_component_definition = (
|
213
206
|
name_to_stream_mapping[declarative_stream.name]
|
214
|
-
.get("retriever")
|
207
|
+
.get("retriever", {})
|
215
208
|
.get("partition_router")
|
216
209
|
)
|
217
210
|
is_without_partition_router_or_cursor = not bool(
|
@@ -233,7 +226,7 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
|
|
233
226
|
cursor = self._constructor.create_concurrent_cursor_from_datetime_based_cursor(
|
234
227
|
state_manager=state_manager,
|
235
228
|
model_type=DatetimeBasedCursorModel,
|
236
|
-
component_definition=incremental_sync_component_definition,
|
229
|
+
component_definition=incremental_sync_component_definition, # type: ignore # Not None because of the if condition above
|
237
230
|
stream_name=declarative_stream.name,
|
238
231
|
stream_namespace=declarative_stream.namespace,
|
239
232
|
config=config or {},
|
@@ -316,10 +309,11 @@ class ConcurrentDeclarativeSource(ManifestDeclarativeSource, Generic[TState]):
|
|
316
309
|
def _is_datetime_incremental_without_partition_routing(
|
317
310
|
self,
|
318
311
|
declarative_stream: DeclarativeStream,
|
319
|
-
incremental_sync_component_definition: Mapping[str, Any],
|
312
|
+
incremental_sync_component_definition: Mapping[str, Any] | None,
|
320
313
|
) -> bool:
|
321
314
|
return (
|
322
|
-
|
315
|
+
incremental_sync_component_definition is not None
|
316
|
+
and bool(incremental_sync_component_definition)
|
323
317
|
and incremental_sync_component_definition.get("type", "")
|
324
318
|
== DatetimeBasedCursorModel.__name__
|
325
319
|
and self._stream_supports_concurrent_partition_processing(
|
@@ -37,17 +37,17 @@ class DatetimeParser:
|
|
37
37
|
return parsed_datetime.replace(tzinfo=datetime.timezone.utc)
|
38
38
|
return parsed_datetime
|
39
39
|
|
40
|
-
def format(self, dt: datetime.datetime, format: str) -> str:
|
40
|
+
def format(self, dt: datetime.datetime, format: str) -> Union[str, int]:
|
41
41
|
# strftime("%s") is unreliable because it ignores the time zone information and assumes the time zone of the system it's running on
|
42
42
|
# It's safer to use the timestamp() method than the %s directive
|
43
43
|
# See https://stackoverflow.com/a/4974930
|
44
44
|
if format == "%s":
|
45
|
-
return
|
45
|
+
return int(dt.timestamp())
|
46
46
|
if format == "%s_as_float":
|
47
|
-
return
|
47
|
+
return float(dt.timestamp())
|
48
48
|
if format == "%ms":
|
49
49
|
# timstamp() returns a float representing the number of seconds since the unix epoch
|
50
|
-
return
|
50
|
+
return int(dt.timestamp() * 1000)
|
51
51
|
else:
|
52
52
|
return dt.strftime(format)
|
53
53
|
|
@@ -7,8 +7,12 @@ version: 1.0.0
|
|
7
7
|
required:
|
8
8
|
- type
|
9
9
|
- check
|
10
|
-
- streams
|
11
10
|
- version
|
11
|
+
anyOf:
|
12
|
+
- required:
|
13
|
+
- streams
|
14
|
+
- required:
|
15
|
+
- dynamic_streams
|
12
16
|
properties:
|
13
17
|
type:
|
14
18
|
type: string
|
@@ -19,6 +23,10 @@ properties:
|
|
19
23
|
type: array
|
20
24
|
items:
|
21
25
|
"$ref": "#/definitions/DeclarativeStream"
|
26
|
+
dynamic_streams:
|
27
|
+
type: array
|
28
|
+
items:
|
29
|
+
"$ref": "#/definitions/DynamicDeclarativeStream"
|
22
30
|
version:
|
23
31
|
type: string
|
24
32
|
description: The version of the Airbyte CDK used to build and test the source.
|
@@ -1321,7 +1329,7 @@ definitions:
|
|
1321
1329
|
type: array
|
1322
1330
|
items:
|
1323
1331
|
- type: string
|
1324
|
-
|
1332
|
+
interpolation_context:
|
1325
1333
|
- config
|
1326
1334
|
examples:
|
1327
1335
|
- ["data"]
|
@@ -2895,6 +2903,96 @@ definitions:
|
|
2895
2903
|
$parameters:
|
2896
2904
|
type: object
|
2897
2905
|
additionalProperties: true
|
2906
|
+
ComponentMappingDefinition:
|
2907
|
+
title: Component Mapping Definition
|
2908
|
+
description: (This component is experimental. Use at your own risk.) Specifies a mapping definition to update or add fields in a record or configuration. This allows dynamic mapping of data by interpolating values into the template based on provided contexts.
|
2909
|
+
type: object
|
2910
|
+
required:
|
2911
|
+
- type
|
2912
|
+
- field_path
|
2913
|
+
- value
|
2914
|
+
properties:
|
2915
|
+
type:
|
2916
|
+
type: string
|
2917
|
+
enum: [ComponentMappingDefinition]
|
2918
|
+
field_path:
|
2919
|
+
title: Field Path
|
2920
|
+
description: A list of potentially nested fields indicating the full path where value will be added or updated.
|
2921
|
+
type: array
|
2922
|
+
items:
|
2923
|
+
- type: string
|
2924
|
+
interpolation_context:
|
2925
|
+
- config
|
2926
|
+
- components_values
|
2927
|
+
- stream_template_config
|
2928
|
+
examples:
|
2929
|
+
- ["data"]
|
2930
|
+
- ["data", "records"]
|
2931
|
+
- ["data", "{{ parameters.name }}"]
|
2932
|
+
- ["data", "*", "record"]
|
2933
|
+
value:
|
2934
|
+
title: Value
|
2935
|
+
description: The dynamic or static value to assign to the key. Interpolated values can be used to dynamically determine the value during runtime.
|
2936
|
+
type: string
|
2937
|
+
interpolation_context:
|
2938
|
+
- config
|
2939
|
+
- stream_template_config
|
2940
|
+
- components_values
|
2941
|
+
examples:
|
2942
|
+
- "{{ components_values['updates'] }}"
|
2943
|
+
- "{{ components_values['MetaData']['LastUpdatedTime'] }}"
|
2944
|
+
- "{{ config['segment_id'] }}"
|
2945
|
+
value_type:
|
2946
|
+
title: Value Type
|
2947
|
+
description: The expected data type of the value. If omitted, the type will be inferred from the value provided.
|
2948
|
+
"$ref": "#/definitions/ValueType"
|
2949
|
+
$parameters:
|
2950
|
+
type: object
|
2951
|
+
additionalProperties: true
|
2952
|
+
HttpComponentsResolver:
|
2953
|
+
type: object
|
2954
|
+
description: (This component is experimental. Use at your own risk.) Component resolve and populates stream templates with components fetched via an HTTP retriever.
|
2955
|
+
properties:
|
2956
|
+
type:
|
2957
|
+
type: string
|
2958
|
+
enum: [HttpComponentsResolver]
|
2959
|
+
retriever:
|
2960
|
+
title: Retriever
|
2961
|
+
description: Component used to coordinate how records are extracted across stream slices and request pages.
|
2962
|
+
anyOf:
|
2963
|
+
- "$ref": "#/definitions/AsyncRetriever"
|
2964
|
+
- "$ref": "#/definitions/CustomRetriever"
|
2965
|
+
- "$ref": "#/definitions/SimpleRetriever"
|
2966
|
+
components_mapping:
|
2967
|
+
type: array
|
2968
|
+
items:
|
2969
|
+
"$ref": "#/definitions/ComponentMappingDefinition"
|
2970
|
+
$parameters:
|
2971
|
+
type: object
|
2972
|
+
additionalProperties: true
|
2973
|
+
required:
|
2974
|
+
- type
|
2975
|
+
- retriever
|
2976
|
+
- components_mapping
|
2977
|
+
DynamicDeclarativeStream:
|
2978
|
+
type: object
|
2979
|
+
description: (This component is experimental. Use at your own risk.) A component that described how will be created declarative streams based on stream template.
|
2980
|
+
properties:
|
2981
|
+
type:
|
2982
|
+
type: string
|
2983
|
+
enum: [DynamicDeclarativeStream]
|
2984
|
+
stream_template:
|
2985
|
+
title: Stream Template
|
2986
|
+
description: Reference to the stream template.
|
2987
|
+
"$ref": "#/definitions/DeclarativeStream"
|
2988
|
+
components_resolver:
|
2989
|
+
title: Components Resolver
|
2990
|
+
description: Component resolve and populates stream templates with components values.
|
2991
|
+
"$ref": "#/definitions/HttpComponentsResolver"
|
2992
|
+
required:
|
2993
|
+
- type
|
2994
|
+
- stream_template
|
2995
|
+
- components_resolver
|
2898
2996
|
interpolation:
|
2899
2997
|
variables:
|
2900
2998
|
- title: config
|
@@ -248,7 +248,7 @@ class DatetimeBasedCursor(DeclarativeCursor):
|
|
248
248
|
return datetime.datetime.min.replace(tzinfo=datetime.timezone.utc)
|
249
249
|
|
250
250
|
def _format_datetime(self, dt: datetime.datetime) -> str:
|
251
|
-
return self._parser.format(dt, self.datetime_format)
|
251
|
+
return str(self._parser.format(dt, self.datetime_format))
|
252
252
|
|
253
253
|
def _partition_daterange(
|
254
254
|
self,
|
@@ -39,6 +39,7 @@ from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import
|
|
39
39
|
from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import (
|
40
40
|
ModelToComponentFactory,
|
41
41
|
)
|
42
|
+
from airbyte_cdk.sources.declarative.resolvers import COMPONENTS_RESOLVER_TYPE_MAPPING
|
42
43
|
from airbyte_cdk.sources.message import MessageRepository
|
43
44
|
from airbyte_cdk.sources.streams.core import Stream
|
44
45
|
from airbyte_cdk.sources.types import ConnectionDefinition
|
@@ -120,7 +121,10 @@ class ManifestDeclarativeSource(DeclarativeSource):
|
|
120
121
|
self._emit_manifest_debug_message(
|
121
122
|
extra_args={"source_name": self.name, "parsed_config": json.dumps(self._source_config)}
|
122
123
|
)
|
123
|
-
|
124
|
+
|
125
|
+
stream_configs = self._stream_configs(self._source_config) + self._dynamic_stream_configs(
|
126
|
+
self._source_config, config
|
127
|
+
)
|
124
128
|
|
125
129
|
source_streams = [
|
126
130
|
self._constructor.create_component(
|
@@ -234,7 +238,8 @@ class ManifestDeclarativeSource(DeclarativeSource):
|
|
234
238
|
)
|
235
239
|
|
236
240
|
streams = self._source_config.get("streams")
|
237
|
-
|
241
|
+
dynamic_streams = self._source_config.get("dynamic_streams")
|
242
|
+
if not (streams or dynamic_streams):
|
238
243
|
raise ValidationError(
|
239
244
|
f"A valid manifest should have at least one stream defined. Got {streams}"
|
240
245
|
)
|
@@ -303,5 +308,51 @@ class ManifestDeclarativeSource(DeclarativeSource):
|
|
303
308
|
s["type"] = "DeclarativeStream"
|
304
309
|
return stream_configs
|
305
310
|
|
311
|
+
def _dynamic_stream_configs(
|
312
|
+
self, manifest: Mapping[str, Any], config: Mapping[str, Any]
|
313
|
+
) -> List[Dict[str, Any]]:
|
314
|
+
dynamic_stream_definitions: List[Dict[str, Any]] = manifest.get("dynamic_streams", [])
|
315
|
+
dynamic_stream_configs: List[Dict[str, Any]] = []
|
316
|
+
|
317
|
+
for dynamic_definition in dynamic_stream_definitions:
|
318
|
+
components_resolver_config = dynamic_definition["components_resolver"]
|
319
|
+
|
320
|
+
if not components_resolver_config:
|
321
|
+
raise ValueError(
|
322
|
+
f"Missing 'components_resolver' in dynamic definition: {dynamic_definition}"
|
323
|
+
)
|
324
|
+
|
325
|
+
resolver_type = components_resolver_config.get("type")
|
326
|
+
if not resolver_type:
|
327
|
+
raise ValueError(
|
328
|
+
f"Missing 'type' in components resolver configuration: {components_resolver_config}"
|
329
|
+
)
|
330
|
+
|
331
|
+
if resolver_type not in COMPONENTS_RESOLVER_TYPE_MAPPING:
|
332
|
+
raise ValueError(
|
333
|
+
f"Invalid components resolver type '{resolver_type}'. "
|
334
|
+
f"Expected one of {list(COMPONENTS_RESOLVER_TYPE_MAPPING.keys())}."
|
335
|
+
)
|
336
|
+
|
337
|
+
if "retriever" in components_resolver_config:
|
338
|
+
components_resolver_config["retriever"]["requester"]["use_cache"] = True
|
339
|
+
|
340
|
+
# Create a resolver for dynamic components based on type
|
341
|
+
components_resolver = self._constructor.create_component(
|
342
|
+
COMPONENTS_RESOLVER_TYPE_MAPPING[resolver_type], components_resolver_config, config
|
343
|
+
)
|
344
|
+
|
345
|
+
stream_template_config = dynamic_definition["stream_template"]
|
346
|
+
|
347
|
+
for dynamic_stream in components_resolver.resolve_components(
|
348
|
+
stream_template_config=stream_template_config
|
349
|
+
):
|
350
|
+
if "type" not in dynamic_stream:
|
351
|
+
dynamic_stream["type"] = "DeclarativeStream"
|
352
|
+
|
353
|
+
dynamic_stream_configs.append(dynamic_stream)
|
354
|
+
|
355
|
+
return dynamic_stream_configs
|
356
|
+
|
306
357
|
def _emit_manifest_debug_message(self, extra_args: dict[str, Any]) -> None:
|
307
358
|
self.logger.debug("declarative source created from manifest", extra=extra_args)
|
@@ -1158,6 +1158,37 @@ class WaitUntilTimeFromHeader(BaseModel):
|
|
1158
1158
|
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
1159
1159
|
|
1160
1160
|
|
1161
|
+
class ComponentMappingDefinition(BaseModel):
|
1162
|
+
type: Literal["ComponentMappingDefinition"]
|
1163
|
+
field_path: List[str] = Field(
|
1164
|
+
...,
|
1165
|
+
description="A list of potentially nested fields indicating the full path where value will be added or updated.",
|
1166
|
+
examples=[
|
1167
|
+
["data"],
|
1168
|
+
["data", "records"],
|
1169
|
+
["data", "{{ parameters.name }}"],
|
1170
|
+
["data", "*", "record"],
|
1171
|
+
],
|
1172
|
+
title="Field Path",
|
1173
|
+
)
|
1174
|
+
value: str = Field(
|
1175
|
+
...,
|
1176
|
+
description="The dynamic or static value to assign to the key. Interpolated values can be used to dynamically determine the value during runtime.",
|
1177
|
+
examples=[
|
1178
|
+
"{{ components_values['updates'] }}",
|
1179
|
+
"{{ components_values['MetaData']['LastUpdatedTime'] }}",
|
1180
|
+
"{{ config['segment_id'] }}",
|
1181
|
+
],
|
1182
|
+
title="Value",
|
1183
|
+
)
|
1184
|
+
value_type: Optional[ValueType] = Field(
|
1185
|
+
None,
|
1186
|
+
description="The expected data type of the value. If omitted, the type will be inferred from the value provided.",
|
1187
|
+
title="Value Type",
|
1188
|
+
)
|
1189
|
+
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
1190
|
+
|
1191
|
+
|
1161
1192
|
class AddedFieldDefinition(BaseModel):
|
1162
1193
|
type: Literal["AddedFieldDefinition"]
|
1163
1194
|
path: List[str] = Field(
|
@@ -1455,13 +1486,40 @@ class CompositeErrorHandler(BaseModel):
|
|
1455
1486
|
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
1456
1487
|
|
1457
1488
|
|
1458
|
-
class
|
1489
|
+
class DeclarativeSource1(BaseModel):
|
1459
1490
|
class Config:
|
1460
1491
|
extra = Extra.forbid
|
1461
1492
|
|
1462
1493
|
type: Literal["DeclarativeSource"]
|
1463
1494
|
check: CheckStream
|
1464
1495
|
streams: List[DeclarativeStream]
|
1496
|
+
dynamic_streams: Optional[List[DynamicDeclarativeStream]] = None
|
1497
|
+
version: str = Field(
|
1498
|
+
...,
|
1499
|
+
description="The version of the Airbyte CDK used to build and test the source.",
|
1500
|
+
)
|
1501
|
+
schemas: Optional[Schemas] = None
|
1502
|
+
definitions: Optional[Dict[str, Any]] = None
|
1503
|
+
spec: Optional[Spec] = None
|
1504
|
+
concurrency_level: Optional[ConcurrencyLevel] = None
|
1505
|
+
metadata: Optional[Dict[str, Any]] = Field(
|
1506
|
+
None,
|
1507
|
+
description="For internal Airbyte use only - DO NOT modify manually. Used by consumers of declarative manifests for storing related metadata.",
|
1508
|
+
)
|
1509
|
+
description: Optional[str] = Field(
|
1510
|
+
None,
|
1511
|
+
description="A description of the connector. It will be presented on the Source documentation page.",
|
1512
|
+
)
|
1513
|
+
|
1514
|
+
|
1515
|
+
class DeclarativeSource2(BaseModel):
|
1516
|
+
class Config:
|
1517
|
+
extra = Extra.forbid
|
1518
|
+
|
1519
|
+
type: Literal["DeclarativeSource"]
|
1520
|
+
check: CheckStream
|
1521
|
+
streams: Optional[List[DeclarativeStream]] = None
|
1522
|
+
dynamic_streams: List[DynamicDeclarativeStream]
|
1465
1523
|
version: str = Field(
|
1466
1524
|
...,
|
1467
1525
|
description="The version of the Airbyte CDK used to build and test the source.",
|
@@ -1480,6 +1538,17 @@ class DeclarativeSource(BaseModel):
|
|
1480
1538
|
)
|
1481
1539
|
|
1482
1540
|
|
1541
|
+
class DeclarativeSource(BaseModel):
|
1542
|
+
class Config:
|
1543
|
+
extra = Extra.forbid
|
1544
|
+
|
1545
|
+
__root__: Union[DeclarativeSource1, DeclarativeSource2] = Field(
|
1546
|
+
...,
|
1547
|
+
description="An API source that extracts data according to its declarative components.",
|
1548
|
+
title="DeclarativeSource",
|
1549
|
+
)
|
1550
|
+
|
1551
|
+
|
1483
1552
|
class SelectiveAuthenticator(BaseModel):
|
1484
1553
|
class Config:
|
1485
1554
|
extra = Extra.allow
|
@@ -1883,8 +1952,32 @@ class SubstreamPartitionRouter(BaseModel):
|
|
1883
1952
|
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
1884
1953
|
|
1885
1954
|
|
1955
|
+
class HttpComponentsResolver(BaseModel):
|
1956
|
+
type: Literal["HttpComponentsResolver"]
|
1957
|
+
retriever: Union[AsyncRetriever, CustomRetriever, SimpleRetriever] = Field(
|
1958
|
+
...,
|
1959
|
+
description="Component used to coordinate how records are extracted across stream slices and request pages.",
|
1960
|
+
title="Retriever",
|
1961
|
+
)
|
1962
|
+
components_mapping: List[ComponentMappingDefinition]
|
1963
|
+
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
|
1964
|
+
|
1965
|
+
|
1966
|
+
class DynamicDeclarativeStream(BaseModel):
|
1967
|
+
type: Literal["DynamicDeclarativeStream"]
|
1968
|
+
stream_template: DeclarativeStream = Field(
|
1969
|
+
..., description="Reference to the stream template.", title="Stream Template"
|
1970
|
+
)
|
1971
|
+
components_resolver: HttpComponentsResolver = Field(
|
1972
|
+
...,
|
1973
|
+
description="Component resolve and populates stream templates with components values.",
|
1974
|
+
title="Components Resolver",
|
1975
|
+
)
|
1976
|
+
|
1977
|
+
|
1886
1978
|
CompositeErrorHandler.update_forward_refs()
|
1887
|
-
|
1979
|
+
DeclarativeSource1.update_forward_refs()
|
1980
|
+
DeclarativeSource2.update_forward_refs()
|
1888
1981
|
SelectiveAuthenticator.update_forward_refs()
|
1889
1982
|
DeclarativeStream.update_forward_refs()
|
1890
1983
|
SessionTokenAuthenticator.update_forward_refs()
|
@@ -31,6 +31,12 @@ DEFAULT_MODEL_TYPES: Mapping[str, str] = {
|
|
31
31
|
# DeclarativeStream
|
32
32
|
"DeclarativeStream.retriever": "SimpleRetriever",
|
33
33
|
"DeclarativeStream.schema_loader": "JsonFileSchemaLoader",
|
34
|
+
# DynamicDeclarativeStream
|
35
|
+
"DynamicDeclarativeStream.stream_template": "DeclarativeStream",
|
36
|
+
"DynamicDeclarativeStream.components_resolver": "HttpComponentsResolver",
|
37
|
+
# HttpComponentsResolver
|
38
|
+
"HttpComponentsResolver.retriever": "SimpleRetriever",
|
39
|
+
"HttpComponentsResolver.components_mapping": "ComponentMappingDefinition",
|
34
40
|
# DefaultErrorHandler
|
35
41
|
"DefaultErrorHandler.response_filters": "HttpResponseFilter",
|
36
42
|
# DefaultPaginator
|