airbyte-cdk 6.48.17.dev0__py3-none-any.whl → 6.49.1__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/cli/source_declarative_manifest/_run.py +69 -10
- airbyte_cdk/connector.py +3 -3
- airbyte_cdk/entrypoint.py +36 -0
- airbyte_cdk/sources/declarative/declarative_component_schema.yaml +277 -69
- airbyte_cdk/sources/declarative/extractors/__init__.py +0 -4
- airbyte_cdk/sources/declarative/manifest_declarative_source.py +3 -1
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py +190 -45
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +155 -60
- airbyte_cdk/sources/declarative/resolvers/components_resolver.py +0 -2
- airbyte_cdk/sources/declarative/resolvers/config_components_resolver.py +14 -49
- airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py +4 -19
- airbyte_cdk/sources/declarative/spec/__init__.py +2 -2
- airbyte_cdk/sources/declarative/spec/spec.py +71 -2
- airbyte_cdk/sources/declarative/transformations/config_transformations/add_fields.py +10 -23
- airbyte_cdk/sources/declarative/transformations/config_transformations/remap_field.py +2 -3
- airbyte_cdk/sources/declarative/validators/dpath_validator.py +1 -1
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/METADATA +1 -1
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/RECORD +22 -24
- airbyte_cdk/sources/declarative/extractors/combined_extractor.py +0 -44
- airbyte_cdk/sources/declarative/extractors/key_value_extractor.py +0 -46
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/LICENSE.txt +0 -0
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/LICENSE_SHORT +0 -0
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/WHEEL +0 -0
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/entry_points.txt +0 -0
@@ -16,15 +16,17 @@ source-declarative-manifest spec
|
|
16
16
|
|
17
17
|
from __future__ import annotations
|
18
18
|
|
19
|
+
import argparse
|
19
20
|
import json
|
20
21
|
import pkgutil
|
21
22
|
import sys
|
22
23
|
import traceback
|
23
|
-
from collections.abc import
|
24
|
+
from collections.abc import MutableMapping
|
24
25
|
from pathlib import Path
|
25
26
|
from typing import Any, cast
|
26
27
|
|
27
28
|
import orjson
|
29
|
+
import yaml
|
28
30
|
|
29
31
|
from airbyte_cdk.entrypoint import AirbyteEntrypoint, launch
|
30
32
|
from airbyte_cdk.models import (
|
@@ -54,7 +56,7 @@ class SourceLocalYaml(YamlDeclarativeSource):
|
|
54
56
|
def __init__(
|
55
57
|
self,
|
56
58
|
catalog: ConfiguredAirbyteCatalog | None,
|
57
|
-
config:
|
59
|
+
config: MutableMapping[str, Any] | None,
|
58
60
|
state: TState,
|
59
61
|
**kwargs: Any,
|
60
62
|
) -> None:
|
@@ -91,7 +93,8 @@ def handle_command(args: list[str]) -> None:
|
|
91
93
|
|
92
94
|
def _get_local_yaml_source(args: list[str]) -> SourceLocalYaml:
|
93
95
|
try:
|
94
|
-
|
96
|
+
parsed_args = AirbyteEntrypoint.parse_args(args)
|
97
|
+
config, catalog, state = _parse_inputs_into_config_catalog_state(parsed_args)
|
95
98
|
return SourceLocalYaml(config=config, catalog=catalog, state=state)
|
96
99
|
except Exception as error:
|
97
100
|
print(
|
@@ -162,14 +165,30 @@ def create_declarative_source(
|
|
162
165
|
connector builder.
|
163
166
|
"""
|
164
167
|
try:
|
165
|
-
config:
|
168
|
+
config: MutableMapping[str, Any] | None
|
166
169
|
catalog: ConfiguredAirbyteCatalog | None
|
167
170
|
state: list[AirbyteStateMessage]
|
168
|
-
|
169
|
-
|
171
|
+
|
172
|
+
parsed_args = AirbyteEntrypoint.parse_args(args)
|
173
|
+
config, catalog, state = _parse_inputs_into_config_catalog_state(parsed_args)
|
174
|
+
|
175
|
+
if config is None:
|
176
|
+
raise ValueError(
|
177
|
+
"Invalid config: `__injected_declarative_manifest` should be provided at the root "
|
178
|
+
"of the config or using the --manifest-path argument."
|
179
|
+
)
|
180
|
+
|
181
|
+
# If a manifest_path is provided in the args, inject it into the config
|
182
|
+
if hasattr(parsed_args, "manifest_path") and parsed_args.manifest_path:
|
183
|
+
injected_manifest = _parse_manifest_from_file(parsed_args.manifest_path)
|
184
|
+
if injected_manifest:
|
185
|
+
config["__injected_declarative_manifest"] = injected_manifest
|
186
|
+
|
187
|
+
if "__injected_declarative_manifest" not in config:
|
170
188
|
raise ValueError(
|
171
189
|
"Invalid config: `__injected_declarative_manifest` should be provided at the root "
|
172
|
-
|
190
|
+
"of the config or using the --manifest-path argument. "
|
191
|
+
f"Config only has keys: {list(config.keys() if config else [])}"
|
173
192
|
)
|
174
193
|
if not isinstance(config["__injected_declarative_manifest"], dict):
|
175
194
|
raise ValueError(
|
@@ -177,6 +196,9 @@ def create_declarative_source(
|
|
177
196
|
f"but got type: {type(config['__injected_declarative_manifest'])}"
|
178
197
|
)
|
179
198
|
|
199
|
+
if hasattr(parsed_args, "components_path") and parsed_args.components_path:
|
200
|
+
_register_components_from_file(parsed_args.components_path)
|
201
|
+
|
180
202
|
return ConcurrentDeclarativeSource(
|
181
203
|
config=config,
|
182
204
|
catalog=catalog,
|
@@ -205,13 +227,12 @@ def create_declarative_source(
|
|
205
227
|
|
206
228
|
|
207
229
|
def _parse_inputs_into_config_catalog_state(
|
208
|
-
|
230
|
+
parsed_args: argparse.Namespace,
|
209
231
|
) -> tuple[
|
210
|
-
|
232
|
+
MutableMapping[str, Any] | None,
|
211
233
|
ConfiguredAirbyteCatalog | None,
|
212
234
|
list[AirbyteStateMessage],
|
213
235
|
]:
|
214
|
-
parsed_args = AirbyteEntrypoint.parse_args(args)
|
215
236
|
config = (
|
216
237
|
ConcurrentDeclarativeSource.read_config(parsed_args.config)
|
217
238
|
if hasattr(parsed_args, "config")
|
@@ -231,6 +252,44 @@ def _parse_inputs_into_config_catalog_state(
|
|
231
252
|
return config, catalog, state
|
232
253
|
|
233
254
|
|
255
|
+
def _parse_manifest_from_file(filepath: str) -> dict[str, Any] | None:
|
256
|
+
"""Extract and parse a manifest file specified in the args."""
|
257
|
+
try:
|
258
|
+
with open(filepath, "r", encoding="utf-8") as manifest_file:
|
259
|
+
manifest_content = yaml.safe_load(manifest_file)
|
260
|
+
if manifest_content is None:
|
261
|
+
raise ValueError(f"Manifest file at {filepath} is empty")
|
262
|
+
if not isinstance(manifest_content, dict):
|
263
|
+
raise ValueError(f"Manifest must be a dictionary, got {type(manifest_content)}")
|
264
|
+
return manifest_content
|
265
|
+
except Exception as error:
|
266
|
+
raise ValueError(f"Failed to load manifest file from {filepath}: {error}")
|
267
|
+
|
268
|
+
|
269
|
+
def _register_components_from_file(filepath: str) -> None:
|
270
|
+
"""Load and register components from a Python file specified in the args."""
|
271
|
+
import importlib.util
|
272
|
+
import sys
|
273
|
+
|
274
|
+
components_path = Path(filepath)
|
275
|
+
|
276
|
+
module_name = "components"
|
277
|
+
sdm_module_name = "source_declarative_manifest.components"
|
278
|
+
|
279
|
+
# Create module spec
|
280
|
+
spec = importlib.util.spec_from_file_location(module_name, components_path)
|
281
|
+
if spec is None or spec.loader is None:
|
282
|
+
raise ImportError(f"Could not load module from {components_path}")
|
283
|
+
|
284
|
+
# Create module and execute code, registering the module before executing its code
|
285
|
+
# To avoid issues with dataclasses that look up the module
|
286
|
+
module = importlib.util.module_from_spec(spec)
|
287
|
+
sys.modules[module_name] = module
|
288
|
+
sys.modules[sdm_module_name] = module
|
289
|
+
|
290
|
+
spec.loader.exec_module(module)
|
291
|
+
|
292
|
+
|
234
293
|
def run() -> None:
|
235
294
|
args: list[str] = sys.argv[1:]
|
236
295
|
handle_command(args)
|
airbyte_cdk/connector.py
CHANGED
@@ -8,7 +8,7 @@ import logging
|
|
8
8
|
import os
|
9
9
|
import pkgutil
|
10
10
|
from abc import ABC, abstractmethod
|
11
|
-
from typing import Any, Generic, Mapping, Optional, Protocol, TypeVar
|
11
|
+
from typing import Any, Generic, Mapping, MutableMapping, Optional, Protocol, TypeVar
|
12
12
|
|
13
13
|
import yaml
|
14
14
|
|
@@ -41,9 +41,9 @@ class BaseConnector(ABC, Generic[TConfig]):
|
|
41
41
|
"""
|
42
42
|
|
43
43
|
@staticmethod
|
44
|
-
def read_config(config_path: str) ->
|
44
|
+
def read_config(config_path: str) -> MutableMapping[str, Any]:
|
45
45
|
config = BaseConnector._read_json_file(config_path)
|
46
|
-
if isinstance(config,
|
46
|
+
if isinstance(config, MutableMapping):
|
47
47
|
return config
|
48
48
|
else:
|
49
49
|
raise ValueError(
|
airbyte_cdk/entrypoint.py
CHANGED
@@ -84,6 +84,18 @@ class AirbyteEntrypoint(object):
|
|
84
84
|
required_check_parser.add_argument(
|
85
85
|
"--config", type=str, required=True, help="path to the json configuration file"
|
86
86
|
)
|
87
|
+
check_parser.add_argument(
|
88
|
+
"--manifest-path",
|
89
|
+
type=str,
|
90
|
+
required=False,
|
91
|
+
help="path to the YAML manifest file to inject into the config",
|
92
|
+
)
|
93
|
+
check_parser.add_argument(
|
94
|
+
"--components-path",
|
95
|
+
type=str,
|
96
|
+
required=False,
|
97
|
+
help="path to the custom components file, if it exists",
|
98
|
+
)
|
87
99
|
|
88
100
|
# discover
|
89
101
|
discover_parser = subparsers.add_parser(
|
@@ -95,6 +107,18 @@ class AirbyteEntrypoint(object):
|
|
95
107
|
required_discover_parser.add_argument(
|
96
108
|
"--config", type=str, required=True, help="path to the json configuration file"
|
97
109
|
)
|
110
|
+
discover_parser.add_argument(
|
111
|
+
"--manifest-path",
|
112
|
+
type=str,
|
113
|
+
required=False,
|
114
|
+
help="path to the YAML manifest file to inject into the config",
|
115
|
+
)
|
116
|
+
discover_parser.add_argument(
|
117
|
+
"--components-path",
|
118
|
+
type=str,
|
119
|
+
required=False,
|
120
|
+
help="path to the custom components file, if it exists",
|
121
|
+
)
|
98
122
|
|
99
123
|
# read
|
100
124
|
read_parser = subparsers.add_parser(
|
@@ -114,6 +138,18 @@ class AirbyteEntrypoint(object):
|
|
114
138
|
required=True,
|
115
139
|
help="path to the catalog used to determine which data to read",
|
116
140
|
)
|
141
|
+
read_parser.add_argument(
|
142
|
+
"--manifest-path",
|
143
|
+
type=str,
|
144
|
+
required=False,
|
145
|
+
help="path to the YAML manifest file to inject into the config",
|
146
|
+
)
|
147
|
+
read_parser.add_argument(
|
148
|
+
"--components-path",
|
149
|
+
type=str,
|
150
|
+
required=False,
|
151
|
+
help="path to the custom components file, if it exists",
|
152
|
+
)
|
117
153
|
|
118
154
|
return main_parser.parse_args(args)
|
119
155
|
|
@@ -1741,54 +1741,6 @@ definitions:
|
|
1741
1741
|
$parameters:
|
1742
1742
|
type: object
|
1743
1743
|
additionalProperties: true
|
1744
|
-
KeyValueExtractor:
|
1745
|
-
title: Key Value Extractor
|
1746
|
-
description: Record extractor that extract with .
|
1747
|
-
type: object
|
1748
|
-
required:
|
1749
|
-
- type
|
1750
|
-
- keys_extractor
|
1751
|
-
- values_extractor
|
1752
|
-
properties:
|
1753
|
-
type:
|
1754
|
-
type: string
|
1755
|
-
enum: [ KeyValueExtractor ]
|
1756
|
-
keys_extractor:
|
1757
|
-
description: placeholder
|
1758
|
-
anyOf:
|
1759
|
-
- "$ref": "#/definitions/DpathExtractor"
|
1760
|
-
- "$ref": "#/definitions/CustomRecordExtractor"
|
1761
|
-
values_extractor:
|
1762
|
-
description: placeholder
|
1763
|
-
anyOf:
|
1764
|
-
- "$ref": "#/definitions/DpathExtractor"
|
1765
|
-
- "$ref": "#/definitions/CustomRecordExtractor"
|
1766
|
-
$parameters:
|
1767
|
-
type: object
|
1768
|
-
additionalProperties: true
|
1769
|
-
CombinedExtractor:
|
1770
|
-
title: Combined Extractor
|
1771
|
-
description: Record extractor that extract with .
|
1772
|
-
type: object
|
1773
|
-
required:
|
1774
|
-
- type
|
1775
|
-
- extractors
|
1776
|
-
properties:
|
1777
|
-
type:
|
1778
|
-
type: string
|
1779
|
-
enum: [ CombinedExtractor ]
|
1780
|
-
extractors:
|
1781
|
-
description: placeholder
|
1782
|
-
type: array
|
1783
|
-
items:
|
1784
|
-
anyOf:
|
1785
|
-
- "$ref": "#/definitions/DpathExtractor"
|
1786
|
-
- "$ref": "#/definitions/CombinedExtractor"
|
1787
|
-
- "$ref": "#/definitions/KeyValueExtractor"
|
1788
|
-
- "$ref": "#/definitions/CustomRecordExtractor"
|
1789
|
-
$parameters:
|
1790
|
-
type: object
|
1791
|
-
additionalProperties: true
|
1792
1744
|
DpathExtractor:
|
1793
1745
|
title: Dpath Extractor
|
1794
1746
|
description: Record extractor that searches a decoded response over a path defined as an array of fields.
|
@@ -2366,12 +2318,6 @@ definitions:
|
|
2366
2318
|
- "$ref": "#/definitions/AsyncRetriever"
|
2367
2319
|
- "$ref": "#/definitions/CustomRetriever"
|
2368
2320
|
- "$ref": "#/definitions/SimpleRetriever"
|
2369
|
-
schema_filter:
|
2370
|
-
title: Schema Filter
|
2371
|
-
description: placeholder
|
2372
|
-
anyOf:
|
2373
|
-
- "$ref": "#/definitions/RecordFilter"
|
2374
|
-
- "$ref": "#/definitions/CustomRecordFilter"
|
2375
2321
|
schema_transformations:
|
2376
2322
|
title: Schema Transformations
|
2377
2323
|
description: A list of transformations to be applied to the schema.
|
@@ -3369,8 +3315,6 @@ definitions:
|
|
3369
3315
|
extractor:
|
3370
3316
|
anyOf:
|
3371
3317
|
- "$ref": "#/definitions/DpathExtractor"
|
3372
|
-
- "$ref": "#/definitions/CombinedExtractor"
|
3373
|
-
- "$ref": "#/definitions/KeyValueExtractor"
|
3374
3318
|
- "$ref": "#/definitions/CustomRecordExtractor"
|
3375
3319
|
record_filter:
|
3376
3320
|
title: Record Filter
|
@@ -3859,6 +3803,61 @@ definitions:
|
|
3859
3803
|
title: Advanced Auth
|
3860
3804
|
description: Advanced specification for configuring the authentication flow.
|
3861
3805
|
"$ref": "#/definitions/AuthFlow"
|
3806
|
+
config_normalization_rules:
|
3807
|
+
title: Config Normalization Rules
|
3808
|
+
type: object
|
3809
|
+
additionalProperties: false
|
3810
|
+
properties:
|
3811
|
+
config_migrations:
|
3812
|
+
title: Config Migrations
|
3813
|
+
description: The discrete migrations that will be applied on the incoming config. Each migration will be applied in the order they are defined.
|
3814
|
+
type: array
|
3815
|
+
items:
|
3816
|
+
"$ref": "#/definitions/ConfigMigration"
|
3817
|
+
default: []
|
3818
|
+
transformations:
|
3819
|
+
title: Transformations
|
3820
|
+
description: The list of transformations that will be applied on the incoming config at the start of each sync. The transformations will be applied in the order they are defined.
|
3821
|
+
type: array
|
3822
|
+
items:
|
3823
|
+
anyOf:
|
3824
|
+
- "$ref": "#/definitions/ConfigRemapField"
|
3825
|
+
- "$ref": "#/definitions/ConfigAddFields"
|
3826
|
+
- "$ref": "#/definitions/ConfigRemoveFields"
|
3827
|
+
default: []
|
3828
|
+
validations:
|
3829
|
+
title: Validations
|
3830
|
+
description: The list of validations that will be performed on the incoming config at the start of each sync.
|
3831
|
+
type: array
|
3832
|
+
items:
|
3833
|
+
anyOf:
|
3834
|
+
- "$ref": "#/definitions/DpathValidator"
|
3835
|
+
- "$ref": "#/definitions/PredicateValidator"
|
3836
|
+
default: []
|
3837
|
+
ConfigMigration:
|
3838
|
+
title: Config Migration
|
3839
|
+
description: A config migration that will be applied on the incoming config at the start of a sync.
|
3840
|
+
type: object
|
3841
|
+
required:
|
3842
|
+
- type
|
3843
|
+
- transformations
|
3844
|
+
properties:
|
3845
|
+
type:
|
3846
|
+
type: string
|
3847
|
+
enum: [ConfigMigration]
|
3848
|
+
description:
|
3849
|
+
type: string
|
3850
|
+
description: The description/purpose of the config migration.
|
3851
|
+
transformations:
|
3852
|
+
title: Transformations
|
3853
|
+
description: The list of transformations that will attempt to be applied on an incoming unmigrated config. The transformations will be applied in the order they are defined.
|
3854
|
+
type: array
|
3855
|
+
items:
|
3856
|
+
anyOf:
|
3857
|
+
- "$ref": "#/definitions/ConfigRemapField"
|
3858
|
+
- "$ref": "#/definitions/ConfigAddFields"
|
3859
|
+
- "$ref": "#/definitions/ConfigRemoveFields"
|
3860
|
+
default: []
|
3862
3861
|
SubstreamPartitionRouter:
|
3863
3862
|
title: Substream Partition Router
|
3864
3863
|
description: Partition router that is used to retrieve records that have been partitioned according to records from the specified parent streams. An example of a parent stream is automobile brands and the substream would be the various car models associated with each branch.
|
@@ -4050,9 +4049,6 @@ definitions:
|
|
4050
4049
|
title: Value Type
|
4051
4050
|
description: The expected data type of the value. If omitted, the type will be inferred from the value provided.
|
4052
4051
|
"$ref": "#/definitions/ValueType"
|
4053
|
-
create_or_update:
|
4054
|
-
type: boolean
|
4055
|
-
default: false
|
4056
4052
|
$parameters:
|
4057
4053
|
type: object
|
4058
4054
|
additionalProperties: true
|
@@ -4104,10 +4100,6 @@ definitions:
|
|
4104
4100
|
- ["data"]
|
4105
4101
|
- ["data", "streams"]
|
4106
4102
|
- ["data", "{{ parameters.name }}"]
|
4107
|
-
default_values:
|
4108
|
-
title: Default Values
|
4109
|
-
description: placeholder
|
4110
|
-
type: array
|
4111
4103
|
$parameters:
|
4112
4104
|
type: object
|
4113
4105
|
additionalProperties: true
|
@@ -4119,11 +4111,7 @@ definitions:
|
|
4119
4111
|
type: string
|
4120
4112
|
enum: [ConfigComponentsResolver]
|
4121
4113
|
stream_config:
|
4122
|
-
|
4123
|
-
- type: array
|
4124
|
-
items:
|
4125
|
-
"$ref": "#/definitions/StreamConfig"
|
4126
|
-
- "$ref": "#/definitions/StreamConfig"
|
4114
|
+
"$ref": "#/definitions/StreamConfig"
|
4127
4115
|
components_mapping:
|
4128
4116
|
type: array
|
4129
4117
|
items:
|
@@ -4152,7 +4140,9 @@ definitions:
|
|
4152
4140
|
stream_template:
|
4153
4141
|
title: Stream Template
|
4154
4142
|
description: Reference to the stream template.
|
4155
|
-
|
4143
|
+
anyOf:
|
4144
|
+
- "$ref": "#/definitions/DeclarativeStream"
|
4145
|
+
- "$ref": "#/definitions/StateDelegatingStream"
|
4156
4146
|
components_resolver:
|
4157
4147
|
title: Components Resolver
|
4158
4148
|
description: Component resolve and populates stream templates with components values.
|
@@ -4231,6 +4221,224 @@ definitions:
|
|
4231
4221
|
description: The GraphQL query to be executed
|
4232
4222
|
default: {}
|
4233
4223
|
additionalProperties: true
|
4224
|
+
DpathValidator:
|
4225
|
+
title: Dpath Validator
|
4226
|
+
description: Validator that extracts the value located at a given field path.
|
4227
|
+
type: object
|
4228
|
+
required:
|
4229
|
+
- type
|
4230
|
+
- field_path
|
4231
|
+
- validation_strategy
|
4232
|
+
properties:
|
4233
|
+
type:
|
4234
|
+
type: string
|
4235
|
+
enum: [DpathValidator]
|
4236
|
+
field_path:
|
4237
|
+
title: Field Path
|
4238
|
+
description: List of potentially nested fields describing the full path of the field to validate. Use "*" to validate all values from an array.
|
4239
|
+
type: array
|
4240
|
+
items:
|
4241
|
+
type: string
|
4242
|
+
interpolation_context:
|
4243
|
+
- config
|
4244
|
+
examples:
|
4245
|
+
- ["data"]
|
4246
|
+
- ["data", "records"]
|
4247
|
+
- ["data", "{{ parameters.name }}"]
|
4248
|
+
- ["data", "*", "record"]
|
4249
|
+
validation_strategy:
|
4250
|
+
title: Validation Strategy
|
4251
|
+
description: The condition that the specified config value will be evaluated against
|
4252
|
+
anyOf:
|
4253
|
+
- "$ref": "#/definitions/ValidateAdheresToSchema"
|
4254
|
+
PredicateValidator:
|
4255
|
+
title: Predicate Validator
|
4256
|
+
description: Validator that applies a validation strategy to a specified value.
|
4257
|
+
type: object
|
4258
|
+
required:
|
4259
|
+
- type
|
4260
|
+
- value
|
4261
|
+
- validation_strategy
|
4262
|
+
properties:
|
4263
|
+
type:
|
4264
|
+
type: string
|
4265
|
+
enum: [PredicateValidator]
|
4266
|
+
value:
|
4267
|
+
title: Value
|
4268
|
+
description: The value to be validated. Can be a literal value or interpolated from configuration.
|
4269
|
+
type:
|
4270
|
+
- string
|
4271
|
+
- number
|
4272
|
+
- object
|
4273
|
+
- array
|
4274
|
+
- boolean
|
4275
|
+
- "null"
|
4276
|
+
interpolation_context:
|
4277
|
+
- config
|
4278
|
+
examples:
|
4279
|
+
- "test-value"
|
4280
|
+
- "{{ config['api_version'] }}"
|
4281
|
+
- "{{ config['tenant_id'] }}"
|
4282
|
+
- 123
|
4283
|
+
validation_strategy:
|
4284
|
+
title: Validation Strategy
|
4285
|
+
description: The validation strategy to apply to the value.
|
4286
|
+
anyOf:
|
4287
|
+
- "$ref": "#/definitions/ValidateAdheresToSchema"
|
4288
|
+
ValidateAdheresToSchema:
|
4289
|
+
title: Validate Adheres To Schema
|
4290
|
+
description: Validates that a user-provided schema adheres to a specified JSON schema.
|
4291
|
+
type: object
|
4292
|
+
required:
|
4293
|
+
- type
|
4294
|
+
- base_schema
|
4295
|
+
properties:
|
4296
|
+
type:
|
4297
|
+
type: string
|
4298
|
+
enum: [ValidateAdheresToSchema]
|
4299
|
+
base_schema:
|
4300
|
+
title: Base JSON Schema
|
4301
|
+
description: The base JSON schema against which the user-provided schema will be validated.
|
4302
|
+
type:
|
4303
|
+
- string
|
4304
|
+
- object
|
4305
|
+
interpolation_context:
|
4306
|
+
- config
|
4307
|
+
examples:
|
4308
|
+
- "{{ config['report_validation_schema'] }}"
|
4309
|
+
- |
|
4310
|
+
'{
|
4311
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
4312
|
+
"title": "Person",
|
4313
|
+
"type": "object",
|
4314
|
+
"properties": {
|
4315
|
+
"name": {
|
4316
|
+
"type": "string",
|
4317
|
+
"description": "The person's name"
|
4318
|
+
},
|
4319
|
+
"age": {
|
4320
|
+
"type": "integer",
|
4321
|
+
"minimum": 0,
|
4322
|
+
"description": "The person's age"
|
4323
|
+
}
|
4324
|
+
},
|
4325
|
+
"required": ["name", "age"]
|
4326
|
+
}'
|
4327
|
+
- $schema: "http://json-schema.org/draft-07/schema#"
|
4328
|
+
title: Person
|
4329
|
+
type: object
|
4330
|
+
properties:
|
4331
|
+
name:
|
4332
|
+
type: string
|
4333
|
+
description: "The person's name"
|
4334
|
+
age:
|
4335
|
+
type: integer
|
4336
|
+
minimum: 0
|
4337
|
+
description: "The person's age"
|
4338
|
+
required:
|
4339
|
+
- name
|
4340
|
+
- age
|
4341
|
+
ConfigRemapField:
|
4342
|
+
title: Remap Field
|
4343
|
+
description: Transformation that remaps a field's value to another value based on a static map.
|
4344
|
+
type: object
|
4345
|
+
required:
|
4346
|
+
- type
|
4347
|
+
- map
|
4348
|
+
- field_path
|
4349
|
+
properties:
|
4350
|
+
type:
|
4351
|
+
type: string
|
4352
|
+
enum: [ConfigRemapField]
|
4353
|
+
map:
|
4354
|
+
title: Value Mapping
|
4355
|
+
description: A mapping of original values to new values. When a field value matches a key in this map, it will be replaced with the corresponding value.
|
4356
|
+
interpolation_context:
|
4357
|
+
- config
|
4358
|
+
type:
|
4359
|
+
- object
|
4360
|
+
- string
|
4361
|
+
additionalProperties: true
|
4362
|
+
examples:
|
4363
|
+
- pending: "in_progress"
|
4364
|
+
done: "completed"
|
4365
|
+
cancelled: "terminated"
|
4366
|
+
- "{{ config['status_mapping'] }}"
|
4367
|
+
field_path:
|
4368
|
+
title: Field Path
|
4369
|
+
description: The path to the field whose value should be remapped. Specified as a list of path components to navigate through nested objects.
|
4370
|
+
interpolation_context:
|
4371
|
+
- config
|
4372
|
+
type: array
|
4373
|
+
items:
|
4374
|
+
type: string
|
4375
|
+
examples:
|
4376
|
+
- ["status"]
|
4377
|
+
- ["data", "status"]
|
4378
|
+
- ["data", "{{ config.name }}", "status"]
|
4379
|
+
- ["data", "*", "status"]
|
4380
|
+
ConfigAddFields:
|
4381
|
+
title: Config Add Fields
|
4382
|
+
description: Transformation that adds fields to a config. The path of the added field can be nested.
|
4383
|
+
type: object
|
4384
|
+
required:
|
4385
|
+
- type
|
4386
|
+
- fields
|
4387
|
+
properties:
|
4388
|
+
type:
|
4389
|
+
type: string
|
4390
|
+
enum: [ConfigAddFields]
|
4391
|
+
fields:
|
4392
|
+
title: Fields
|
4393
|
+
description: A list of transformations (path and corresponding value) that will be added to the config.
|
4394
|
+
type: array
|
4395
|
+
items:
|
4396
|
+
"$ref": "#/definitions/AddedFieldDefinition"
|
4397
|
+
condition:
|
4398
|
+
description: Fields will be added if expression is evaluated to True.
|
4399
|
+
type: string
|
4400
|
+
default: ""
|
4401
|
+
interpolation_context:
|
4402
|
+
- config
|
4403
|
+
- property
|
4404
|
+
examples:
|
4405
|
+
- "{{ config['environemnt'] == 'sandbox' }}"
|
4406
|
+
- "{{ property is integer }}"
|
4407
|
+
- "{{ property|length > 5 }}"
|
4408
|
+
- "{{ property == 'some_string_to_match' }}"
|
4409
|
+
ConfigRemoveFields:
|
4410
|
+
title: Config Remove Fields
|
4411
|
+
description: Transformation that removes a field from the config.
|
4412
|
+
type: object
|
4413
|
+
required:
|
4414
|
+
- type
|
4415
|
+
- field_pointers
|
4416
|
+
properties:
|
4417
|
+
type:
|
4418
|
+
type: string
|
4419
|
+
enum: [ConfigRemoveFields]
|
4420
|
+
field_pointers:
|
4421
|
+
title: Field Pointers
|
4422
|
+
description: A list of field pointers to be removed from the config.
|
4423
|
+
type: array
|
4424
|
+
items:
|
4425
|
+
items:
|
4426
|
+
type: string
|
4427
|
+
examples:
|
4428
|
+
- ["tags"]
|
4429
|
+
- [["content", "html"], ["content", "plain_text"]]
|
4430
|
+
condition:
|
4431
|
+
description: Fields will be removed if expression is evaluated to True.
|
4432
|
+
type: string
|
4433
|
+
default: ""
|
4434
|
+
interpolation_context:
|
4435
|
+
- config
|
4436
|
+
- property
|
4437
|
+
examples:
|
4438
|
+
- "{{ config['environemnt'] == 'sandbox' }}"
|
4439
|
+
- "{{ property is integer }}"
|
4440
|
+
- "{{ property|length > 5 }}"
|
4441
|
+
- "{{ property == 'some_string_to_match' }}"
|
4234
4442
|
interpolation:
|
4235
4443
|
variables:
|
4236
4444
|
- title: config
|
@@ -2,10 +2,8 @@
|
|
2
2
|
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
3
|
#
|
4
4
|
|
5
|
-
from airbyte_cdk.sources.declarative.extractors.combined_extractor import CombinedExtractor
|
6
5
|
from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor
|
7
6
|
from airbyte_cdk.sources.declarative.extractors.http_selector import HttpSelector
|
8
|
-
from airbyte_cdk.sources.declarative.extractors.key_value_extractor import KeyValueExtractor
|
9
7
|
from airbyte_cdk.sources.declarative.extractors.record_filter import RecordFilter
|
10
8
|
from airbyte_cdk.sources.declarative.extractors.record_selector import RecordSelector
|
11
9
|
from airbyte_cdk.sources.declarative.extractors.response_to_file_extractor import (
|
@@ -20,6 +18,4 @@ __all__ = [
|
|
20
18
|
"RecordFilter",
|
21
19
|
"RecordSelector",
|
22
20
|
"ResponseToFileExtractor",
|
23
|
-
"KeyValueExtractor",
|
24
|
-
"CombinedExtractor",
|
25
21
|
]
|
@@ -262,7 +262,9 @@ class ManifestDeclarativeSource(DeclarativeSource):
|
|
262
262
|
}
|
263
263
|
)
|
264
264
|
|
265
|
-
stream_configs = self._stream_configs(self._source_config) + self.
|
265
|
+
stream_configs = self._stream_configs(self._source_config) + self._dynamic_stream_configs(
|
266
|
+
self._source_config, config
|
267
|
+
)
|
266
268
|
|
267
269
|
api_budget_model = self._source_config.get("api_budget")
|
268
270
|
if api_budget_model:
|