airbyte-cdk 6.48.17.dev0__py3-none-any.whl → 6.49.0__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 +274 -68
  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 +189 -44
  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.0.dist-info}/METADATA +1 -1
  18. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.0.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.0.dist-info}/LICENSE.txt +0 -0
  22. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.0.dist-info}/LICENSE_SHORT +0 -0
  23. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.0.dist-info}/WHEEL +0 -0
  24. {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.0.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:
@@ -4231,6 +4219,224 @@ definitions:
4231
4219
  description: The GraphQL query to be executed
4232
4220
  default: {}
4233
4221
  additionalProperties: true
4222
+ DpathValidator:
4223
+ title: Dpath Validator
4224
+ description: Validator that extracts the value located at a given field path.
4225
+ type: object
4226
+ required:
4227
+ - type
4228
+ - field_path
4229
+ - validation_strategy
4230
+ properties:
4231
+ type:
4232
+ type: string
4233
+ enum: [DpathValidator]
4234
+ field_path:
4235
+ title: Field Path
4236
+ description: List of potentially nested fields describing the full path of the field to validate. Use "*" to validate all values from an array.
4237
+ type: array
4238
+ items:
4239
+ type: string
4240
+ interpolation_context:
4241
+ - config
4242
+ examples:
4243
+ - ["data"]
4244
+ - ["data", "records"]
4245
+ - ["data", "{{ parameters.name }}"]
4246
+ - ["data", "*", "record"]
4247
+ validation_strategy:
4248
+ title: Validation Strategy
4249
+ description: The condition that the specified config value will be evaluated against
4250
+ anyOf:
4251
+ - "$ref": "#/definitions/ValidateAdheresToSchema"
4252
+ PredicateValidator:
4253
+ title: Predicate Validator
4254
+ description: Validator that applies a validation strategy to a specified value.
4255
+ type: object
4256
+ required:
4257
+ - type
4258
+ - value
4259
+ - validation_strategy
4260
+ properties:
4261
+ type:
4262
+ type: string
4263
+ enum: [PredicateValidator]
4264
+ value:
4265
+ title: Value
4266
+ description: The value to be validated. Can be a literal value or interpolated from configuration.
4267
+ type:
4268
+ - string
4269
+ - number
4270
+ - object
4271
+ - array
4272
+ - boolean
4273
+ - "null"
4274
+ interpolation_context:
4275
+ - config
4276
+ examples:
4277
+ - "test-value"
4278
+ - "{{ config['api_version'] }}"
4279
+ - "{{ config['tenant_id'] }}"
4280
+ - 123
4281
+ validation_strategy:
4282
+ title: Validation Strategy
4283
+ description: The validation strategy to apply to the value.
4284
+ anyOf:
4285
+ - "$ref": "#/definitions/ValidateAdheresToSchema"
4286
+ ValidateAdheresToSchema:
4287
+ title: Validate Adheres To Schema
4288
+ description: Validates that a user-provided schema adheres to a specified JSON schema.
4289
+ type: object
4290
+ required:
4291
+ - type
4292
+ - base_schema
4293
+ properties:
4294
+ type:
4295
+ type: string
4296
+ enum: [ValidateAdheresToSchema]
4297
+ base_schema:
4298
+ title: Base JSON Schema
4299
+ description: The base JSON schema against which the user-provided schema will be validated.
4300
+ type:
4301
+ - string
4302
+ - object
4303
+ interpolation_context:
4304
+ - config
4305
+ examples:
4306
+ - "{{ config['report_validation_schema'] }}"
4307
+ - |
4308
+ '{
4309
+ "$schema": "http://json-schema.org/draft-07/schema#",
4310
+ "title": "Person",
4311
+ "type": "object",
4312
+ "properties": {
4313
+ "name": {
4314
+ "type": "string",
4315
+ "description": "The person's name"
4316
+ },
4317
+ "age": {
4318
+ "type": "integer",
4319
+ "minimum": 0,
4320
+ "description": "The person's age"
4321
+ }
4322
+ },
4323
+ "required": ["name", "age"]
4324
+ }'
4325
+ - $schema: "http://json-schema.org/draft-07/schema#"
4326
+ title: Person
4327
+ type: object
4328
+ properties:
4329
+ name:
4330
+ type: string
4331
+ description: "The person's name"
4332
+ age:
4333
+ type: integer
4334
+ minimum: 0
4335
+ description: "The person's age"
4336
+ required:
4337
+ - name
4338
+ - age
4339
+ ConfigRemapField:
4340
+ title: Remap Field
4341
+ description: Transformation that remaps a field's value to another value based on a static map.
4342
+ type: object
4343
+ required:
4344
+ - type
4345
+ - map
4346
+ - field_path
4347
+ properties:
4348
+ type:
4349
+ type: string
4350
+ enum: [ConfigRemapField]
4351
+ map:
4352
+ title: Value Mapping
4353
+ 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.
4354
+ interpolation_context:
4355
+ - config
4356
+ type:
4357
+ - object
4358
+ - string
4359
+ additionalProperties: true
4360
+ examples:
4361
+ - pending: "in_progress"
4362
+ done: "completed"
4363
+ cancelled: "terminated"
4364
+ - "{{ config['status_mapping'] }}"
4365
+ field_path:
4366
+ title: Field Path
4367
+ description: The path to the field whose value should be remapped. Specified as a list of path components to navigate through nested objects.
4368
+ interpolation_context:
4369
+ - config
4370
+ type: array
4371
+ items:
4372
+ type: string
4373
+ examples:
4374
+ - ["status"]
4375
+ - ["data", "status"]
4376
+ - ["data", "{{ config.name }}", "status"]
4377
+ - ["data", "*", "status"]
4378
+ ConfigAddFields:
4379
+ title: Config Add Fields
4380
+ description: Transformation that adds fields to a config. The path of the added field can be nested.
4381
+ type: object
4382
+ required:
4383
+ - type
4384
+ - fields
4385
+ properties:
4386
+ type:
4387
+ type: string
4388
+ enum: [ConfigAddFields]
4389
+ fields:
4390
+ title: Fields
4391
+ description: A list of transformations (path and corresponding value) that will be added to the config.
4392
+ type: array
4393
+ items:
4394
+ "$ref": "#/definitions/AddedFieldDefinition"
4395
+ condition:
4396
+ description: Fields will be added if expression is evaluated to True.
4397
+ type: string
4398
+ default: ""
4399
+ interpolation_context:
4400
+ - config
4401
+ - property
4402
+ examples:
4403
+ - "{{ config['environemnt'] == 'sandbox' }}"
4404
+ - "{{ property is integer }}"
4405
+ - "{{ property|length > 5 }}"
4406
+ - "{{ property == 'some_string_to_match' }}"
4407
+ ConfigRemoveFields:
4408
+ title: Config Remove Fields
4409
+ description: Transformation that removes a field from the config.
4410
+ type: object
4411
+ required:
4412
+ - type
4413
+ - field_pointers
4414
+ properties:
4415
+ type:
4416
+ type: string
4417
+ enum: [ConfigRemoveFields]
4418
+ field_pointers:
4419
+ title: Field Pointers
4420
+ description: A list of field pointers to be removed from the config.
4421
+ type: array
4422
+ items:
4423
+ items:
4424
+ type: string
4425
+ examples:
4426
+ - ["tags"]
4427
+ - [["content", "html"], ["content", "plain_text"]]
4428
+ condition:
4429
+ description: Fields will be removed if expression is evaluated to True.
4430
+ type: string
4431
+ default: ""
4432
+ interpolation_context:
4433
+ - config
4434
+ - property
4435
+ examples:
4436
+ - "{{ config['environemnt'] == 'sandbox' }}"
4437
+ - "{{ property is integer }}"
4438
+ - "{{ property|length > 5 }}"
4439
+ - "{{ property == 'some_string_to_match' }}"
4234
4440
  interpolation:
4235
4441
  variables:
4236
4442
  - 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: