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.
Files changed (24) hide show
  1. airbyte_cdk/cli/source_declarative_manifest/_run.py +69 -10
  2. airbyte_cdk/connector.py +3 -3
  3. airbyte_cdk/entrypoint.py +36 -0
  4. airbyte_cdk/sources/declarative/declarative_component_schema.yaml +277 -69
  5. airbyte_cdk/sources/declarative/extractors/__init__.py +0 -4
  6. airbyte_cdk/sources/declarative/manifest_declarative_source.py +3 -1
  7. airbyte_cdk/sources/declarative/models/declarative_component_schema.py +190 -45
  8. airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +155 -60
  9. airbyte_cdk/sources/declarative/resolvers/components_resolver.py +0 -2
  10. airbyte_cdk/sources/declarative/resolvers/config_components_resolver.py +14 -49
  11. airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py +4 -19
  12. airbyte_cdk/sources/declarative/spec/__init__.py +2 -2
  13. airbyte_cdk/sources/declarative/spec/spec.py +71 -2
  14. airbyte_cdk/sources/declarative/transformations/config_transformations/add_fields.py +10 -23
  15. airbyte_cdk/sources/declarative/transformations/config_transformations/remap_field.py +2 -3
  16. airbyte_cdk/sources/declarative/validators/dpath_validator.py +1 -1
  17. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/METADATA +1 -1
  18. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/RECORD +22 -24
  19. airbyte_cdk/sources/declarative/extractors/combined_extractor.py +0 -44
  20. airbyte_cdk/sources/declarative/extractors/key_value_extractor.py +0 -46
  21. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/LICENSE.txt +0 -0
  22. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/LICENSE_SHORT +0 -0
  23. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/WHEEL +0 -0
  24. {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 Mapping
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: Mapping[str, Any] | None,
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
- config, catalog, state = _parse_inputs_into_config_catalog_state(args)
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: Mapping[str, Any] | None
168
+ config: MutableMapping[str, Any] | None
166
169
  catalog: ConfiguredAirbyteCatalog | None
167
170
  state: list[AirbyteStateMessage]
168
- config, catalog, state = _parse_inputs_into_config_catalog_state(args)
169
- if config is None or "__injected_declarative_manifest" not in config:
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
- f"of the config but config only has keys: {list(config.keys() if config else [])}"
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
- args: list[str],
230
+ parsed_args: argparse.Namespace,
209
231
  ) -> tuple[
210
- Mapping[str, Any] | None,
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) -> Mapping[str, Any]:
44
+ def read_config(config_path: str) -> MutableMapping[str, Any]:
45
45
  config = BaseConnector._read_json_file(config_path)
46
- if isinstance(config, Mapping):
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
- anyOf:
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
- "$ref": "#/definitions/DeclarativeStream"
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.dynamic_streams
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: