airbyte-cdk 6.48.15__py3-none-any.whl → 6.48.17.dev0__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.
@@ -39,6 +39,7 @@ poetry run airbyte-cdk connector --help
39
39
  """
40
40
 
41
41
  import os
42
+ import sys
42
43
  from pathlib import Path
43
44
  from types import ModuleType
44
45
 
@@ -166,10 +167,11 @@ def test(
166
167
  click.echo(f"Collect only: {collect_only}")
167
168
  click.echo(f"Pytest args: {pytest_args}")
168
169
  click.echo("Invoking Pytest...")
169
- pytest.main(
170
+ exit_code = pytest.main(
170
171
  pytest_args,
171
172
  plugins=[],
172
173
  )
174
+ sys.exit(exit_code)
173
175
 
174
176
 
175
177
  __all__ = [
@@ -49,7 +49,12 @@ from airbyte_cdk.utils.connector_paths import (
49
49
  resolve_connector_name_and_directory,
50
50
  )
51
51
 
52
- AIRBYTE_INTERNAL_GCP_PROJECT = "dataline-integration-testing"
52
+ GCP_PROJECT_ID: str = os.environ.get("GCP_PROJECT_ID", "") or "dataline-integration-testing"
53
+ # We put the `or` outside the `get()` because we want the `GCP_PROJECT_ID`
54
+ # env var to be ignored if it contains an empty string, such as in CI where the
55
+ # workflow might set it to a value that is itself actually missing or unset.
56
+ """The GCP project ID to use for fetching integration test secrets."""
57
+
53
58
  CONNECTOR_LABEL = "connector"
54
59
  GLOBAL_MASK_KEYS_URL = "https://connectors.airbyte.com/files/registries/v0/specs_secrets_mask.yaml"
55
60
 
@@ -83,8 +88,11 @@ def secrets_cli_group() -> None:
83
88
  @click.option(
84
89
  "--gcp-project-id",
85
90
  type=str,
86
- default=AIRBYTE_INTERNAL_GCP_PROJECT,
87
- help=f"GCP project ID. Defaults to '{AIRBYTE_INTERNAL_GCP_PROJECT}'.",
91
+ default=GCP_PROJECT_ID,
92
+ help=(
93
+ "GCP project ID for retrieving integration tests credentials. "
94
+ "Defaults to the value of the `GCP_PROJECT_ID` environment variable, if set."
95
+ ),
88
96
  )
89
97
  @click.option(
90
98
  "--print-ci-secrets-masks",
@@ -95,7 +103,7 @@ def secrets_cli_group() -> None:
95
103
  )
96
104
  def fetch(
97
105
  connector: str | Path | None = None,
98
- gcp_project_id: str = AIRBYTE_INTERNAL_GCP_PROJECT,
106
+ gcp_project_id: str = GCP_PROJECT_ID,
99
107
  print_ci_secrets_masks: bool = False,
100
108
  ) -> None:
101
109
  """Fetch secrets for a connector from Google Secret Manager.
@@ -192,41 +200,41 @@ def fetch(
192
200
 
193
201
 
194
202
  @secrets_cli_group.command("list")
195
- @click.option(
196
- "--connector-name",
203
+ @click.argument(
204
+ "connector",
205
+ required=False,
197
206
  type=str,
198
- help="Name of the connector to fetch secrets for. Ignored if --connector-directory is provided.",
199
- )
200
- @click.option(
201
- "--connector-directory",
202
- type=click.Path(exists=True, file_okay=False, path_type=Path),
203
- help="Path to the connector directory.",
207
+ metavar="[CONNECTOR]",
204
208
  )
205
209
  @click.option(
206
210
  "--gcp-project-id",
207
211
  type=str,
208
- default=AIRBYTE_INTERNAL_GCP_PROJECT,
209
- help=f"GCP project ID. Defaults to '{AIRBYTE_INTERNAL_GCP_PROJECT}'.",
212
+ default=GCP_PROJECT_ID,
213
+ help=(
214
+ "GCP project ID for retrieving integration tests credentials. "
215
+ "Defaults to the value of the `GCP_PROJECT_ID` environment variable, if set."
216
+ ),
210
217
  )
211
218
  def list_(
212
- connector_name: str | None = None,
213
- connector_directory: Path | None = None,
214
- gcp_project_id: str = AIRBYTE_INTERNAL_GCP_PROJECT,
219
+ connector: str | Path | None = None,
220
+ *,
221
+ gcp_project_id: str = GCP_PROJECT_ID,
215
222
  ) -> None:
216
223
  """List secrets for a connector from Google Secret Manager.
217
224
 
218
225
  This command fetches secrets for a connector from Google Secret Manager and prints
219
226
  them as a table.
220
227
 
228
+ [CONNECTOR] can be a connector name (e.g. 'source-pokeapi'), a path to a connector directory, or omitted to use the current working directory.
229
+ If a string containing '/' is provided, it is treated as a path. Otherwise, it is treated as a connector name.
230
+
221
231
  If no connector name or directory is provided, we will look within the current working
222
232
  directory. If the current working directory is not a connector directory (e.g. starting
223
233
  with 'source-') and no connector name or path is provided, the process will fail.
224
234
  """
225
235
  click.echo("Scanning secrets...", err=True)
226
236
 
227
- connector_name = connector_name or resolve_connector_name(
228
- connector_directory=connector_directory or Path().resolve().absolute(),
229
- )
237
+ connector_name, _ = resolve_connector_name_and_directory(connector)
230
238
  secrets: list[Secret] = _fetch_secret_handles( # type: ignore
231
239
  connector_name=connector_name,
232
240
  gcp_project_id=gcp_project_id,
@@ -303,7 +311,7 @@ def _get_secret_url(secret_name: str, gcp_project_id: str) -> str:
303
311
 
304
312
  def _fetch_secret_handles(
305
313
  connector_name: str,
306
- gcp_project_id: str = AIRBYTE_INTERNAL_GCP_PROJECT,
314
+ gcp_project_id: str = GCP_PROJECT_ID,
307
315
  ) -> list["Secret"]: # type: ignore
308
316
  """Fetch secrets from Google Secret Manager."""
309
317
  if not secretmanager:
@@ -1741,6 +1741,54 @@ 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
1744
1792
  DpathExtractor:
1745
1793
  title: Dpath Extractor
1746
1794
  description: Record extractor that searches a decoded response over a path defined as an array of fields.
@@ -2318,6 +2366,12 @@ definitions:
2318
2366
  - "$ref": "#/definitions/AsyncRetriever"
2319
2367
  - "$ref": "#/definitions/CustomRetriever"
2320
2368
  - "$ref": "#/definitions/SimpleRetriever"
2369
+ schema_filter:
2370
+ title: Schema Filter
2371
+ description: placeholder
2372
+ anyOf:
2373
+ - "$ref": "#/definitions/RecordFilter"
2374
+ - "$ref": "#/definitions/CustomRecordFilter"
2321
2375
  schema_transformations:
2322
2376
  title: Schema Transformations
2323
2377
  description: A list of transformations to be applied to the schema.
@@ -3315,6 +3369,8 @@ definitions:
3315
3369
  extractor:
3316
3370
  anyOf:
3317
3371
  - "$ref": "#/definitions/DpathExtractor"
3372
+ - "$ref": "#/definitions/CombinedExtractor"
3373
+ - "$ref": "#/definitions/KeyValueExtractor"
3318
3374
  - "$ref": "#/definitions/CustomRecordExtractor"
3319
3375
  record_filter:
3320
3376
  title: Record Filter
@@ -3994,6 +4050,9 @@ definitions:
3994
4050
  title: Value Type
3995
4051
  description: The expected data type of the value. If omitted, the type will be inferred from the value provided.
3996
4052
  "$ref": "#/definitions/ValueType"
4053
+ create_or_update:
4054
+ type: boolean
4055
+ default: false
3997
4056
  $parameters:
3998
4057
  type: object
3999
4058
  additionalProperties: true
@@ -4045,6 +4104,10 @@ definitions:
4045
4104
  - ["data"]
4046
4105
  - ["data", "streams"]
4047
4106
  - ["data", "{{ parameters.name }}"]
4107
+ default_values:
4108
+ title: Default Values
4109
+ description: placeholder
4110
+ type: array
4048
4111
  $parameters:
4049
4112
  type: object
4050
4113
  additionalProperties: true
@@ -4056,7 +4119,11 @@ definitions:
4056
4119
  type: string
4057
4120
  enum: [ConfigComponentsResolver]
4058
4121
  stream_config:
4059
- "$ref": "#/definitions/StreamConfig"
4122
+ anyOf:
4123
+ - type: array
4124
+ items:
4125
+ "$ref": "#/definitions/StreamConfig"
4126
+ - "$ref": "#/definitions/StreamConfig"
4060
4127
  components_mapping:
4061
4128
  type: array
4062
4129
  items:
@@ -2,8 +2,10 @@
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
5
6
  from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor
6
7
  from airbyte_cdk.sources.declarative.extractors.http_selector import HttpSelector
8
+ from airbyte_cdk.sources.declarative.extractors.key_value_extractor import KeyValueExtractor
7
9
  from airbyte_cdk.sources.declarative.extractors.record_filter import RecordFilter
8
10
  from airbyte_cdk.sources.declarative.extractors.record_selector import RecordSelector
9
11
  from airbyte_cdk.sources.declarative.extractors.response_to_file_extractor import (
@@ -18,4 +20,6 @@ __all__ = [
18
20
  "RecordFilter",
19
21
  "RecordSelector",
20
22
  "ResponseToFileExtractor",
23
+ "KeyValueExtractor",
24
+ "CombinedExtractor",
21
25
  ]
@@ -0,0 +1,44 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass, field
6
+ from itertools import islice
7
+ from typing import Any, Iterable, List, Mapping, MutableMapping, Union
8
+
9
+ import dpath
10
+ import requests
11
+
12
+ from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder
13
+ from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor
14
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
15
+ from airbyte_cdk.sources.types import Config
16
+
17
+
18
+ @dataclass
19
+ class CombinedExtractor(RecordExtractor):
20
+ """
21
+ Extractor that combines keys and values from two separate extractors.
22
+
23
+ The `keys_extractor` and `values_extractor` extract records independently
24
+ from the response. Their outputs are zipped together to form key-value mappings.
25
+
26
+ Each key from `keys_extractor` should correspond to a key in the resulting dictionary,
27
+ and each value from `values_extractor` is the value for that key.
28
+
29
+ Example:
30
+ keys_extractor -> yields: ["name", "age"]
31
+ values_extractor -> yields: ["Alice", 30]
32
+ result: { "name": "Alice", "age": 30 }
33
+ """
34
+
35
+ extractors: List[RecordExtractor]
36
+
37
+ def extract_records(self, response: requests.Response) -> Iterable[MutableMapping[Any, Any]]:
38
+ extractors_records = [extractor.extract_records(response) for extractor in self.extractors]
39
+
40
+ for records in zip(*extractors_records):
41
+ merged = {}
42
+ for record in records:
43
+ merged.update(record) # merge all fields
44
+ yield merged
@@ -0,0 +1,46 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass, field
6
+ from itertools import islice
7
+ from typing import Any, Iterable, List, Mapping, MutableMapping, Union
8
+
9
+ import dpath
10
+ import requests
11
+
12
+ from airbyte_cdk.sources.declarative.decoders import Decoder, JsonDecoder
13
+ from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor
14
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
15
+ from airbyte_cdk.sources.types import Config
16
+
17
+
18
+ @dataclass
19
+ class KeyValueExtractor(RecordExtractor):
20
+ """
21
+ Extractor that combines keys and values from two separate extractors.
22
+
23
+ The `keys_extractor` and `values_extractor` extract records independently
24
+ from the response. Their outputs are zipped together to form key-value mappings.
25
+
26
+ Each key from `keys_extractor` should correspond to a key in the resulting dictionary,
27
+ and each value from `values_extractor` is the value for that key.
28
+
29
+ Example:
30
+ keys_extractor -> yields: ["name", "age"]
31
+ values_extractor -> yields: ["Alice", 30]
32
+ result: { "name": "Alice", "age": 30 }
33
+ """
34
+
35
+ keys_extractor: RecordExtractor
36
+ values_extractor: RecordExtractor
37
+
38
+ def extract_records(self, response: requests.Response) -> Iterable[MutableMapping[Any, Any]]:
39
+ keys = list(self.keys_extractor.extract_records(response))
40
+ values = self.values_extractor.extract_records(response)
41
+
42
+ while True:
43
+ chunk = list(islice(values, len(keys)))
44
+ if not chunk:
45
+ break
46
+ yield dict(zip(keys, chunk))
@@ -262,9 +262,7 @@ class ManifestDeclarativeSource(DeclarativeSource):
262
262
  }
263
263
  )
264
264
 
265
- stream_configs = self._stream_configs(self._source_config) + self._dynamic_stream_configs(
266
- self._source_config, config
267
- )
265
+ stream_configs = self._stream_configs(self._source_config) + self.dynamic_streams
268
266
 
269
267
  api_budget_model = self._source_config.get("api_budget")
270
268
  if api_budget_model:
@@ -1,5 +1,3 @@
1
- # Copyright (c) 2025 Airbyte, Inc., all rights reserved.
2
-
3
1
  # generated by datamodel-codegen:
4
2
  # filename: declarative_component_schema.yaml
5
3
 
@@ -1480,6 +1478,7 @@ class ComponentMappingDefinition(BaseModel):
1480
1478
  description="The expected data type of the value. If omitted, the type will be inferred from the value provided.",
1481
1479
  title="Value Type",
1482
1480
  )
1481
+ create_or_update: Optional[bool] = False
1483
1482
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1484
1483
 
1485
1484
 
@@ -1491,12 +1490,13 @@ class StreamConfig(BaseModel):
1491
1490
  examples=[["data"], ["data", "streams"], ["data", "{{ parameters.name }}"]],
1492
1491
  title="Configs Pointer",
1493
1492
  )
1493
+ default_values: Optional[List] = Field(None, description="placeholder", title="Default Values")
1494
1494
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1495
1495
 
1496
1496
 
1497
1497
  class ConfigComponentsResolver(BaseModel):
1498
1498
  type: Literal["ConfigComponentsResolver"]
1499
- stream_config: StreamConfig
1499
+ stream_config: Union[List[StreamConfig], StreamConfig]
1500
1500
  components_mapping: List[ComponentMappingDefinition]
1501
1501
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1502
1502
 
@@ -1844,6 +1844,25 @@ class DefaultPaginator(BaseModel):
1844
1844
  parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1845
1845
 
1846
1846
 
1847
+ class KeyValueExtractor(BaseModel):
1848
+ type: Literal["KeyValueExtractor"]
1849
+ keys_extractor: Union[DpathExtractor, CustomRecordExtractor] = Field(
1850
+ ..., description="placeholder"
1851
+ )
1852
+ values_extractor: Union[DpathExtractor, CustomRecordExtractor] = Field(
1853
+ ..., description="placeholder"
1854
+ )
1855
+ parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1856
+
1857
+
1858
+ class CombinedExtractor(BaseModel):
1859
+ type: Literal["CombinedExtractor"]
1860
+ extractors: List[
1861
+ Union[DpathExtractor, CombinedExtractor, KeyValueExtractor, CustomRecordExtractor]
1862
+ ] = Field(..., description="placeholder")
1863
+ parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
1864
+
1865
+
1847
1866
  class SessionTokenRequestApiKeyAuthenticator(BaseModel):
1848
1867
  type: Literal["ApiKey"]
1849
1868
  inject_into: RequestOption = Field(
@@ -1881,7 +1900,7 @@ class ListPartitionRouter(BaseModel):
1881
1900
 
1882
1901
  class RecordSelector(BaseModel):
1883
1902
  type: Literal["RecordSelector"]
1884
- extractor: Union[DpathExtractor, CustomRecordExtractor]
1903
+ extractor: Union[DpathExtractor, CombinedExtractor, KeyValueExtractor, CustomRecordExtractor]
1885
1904
  record_filter: Optional[Union[RecordFilter, CustomRecordFilter]] = Field(
1886
1905
  None,
1887
1906
  description="Responsible for filtering records to be emitted by the Source.",
@@ -2164,7 +2183,7 @@ class DeclarativeStream(BaseModel):
2164
2183
  ]
2165
2184
  ] = Field(
2166
2185
  None,
2167
- description="Component used to retrieve the schema for the current stream.",
2186
+ description="One or many schema loaders can be used to retrieve the schema for the current stream. When multiple schema loaders are defined, schema properties will be merged together. Schema loaders defined first taking precedence in the event of a conflict.",
2168
2187
  title="Schema Loader",
2169
2188
  )
2170
2189
  transformations: Optional[
@@ -2414,6 +2433,9 @@ class DynamicSchemaLoader(BaseModel):
2414
2433
  description="Component used to coordinate how records are extracted across stream slices and request pages.",
2415
2434
  title="Retriever",
2416
2435
  )
2436
+ schema_filter: Optional[Union[RecordFilter, CustomRecordFilter]] = Field(
2437
+ None, description="placeholder", title="Schema Filter"
2438
+ )
2417
2439
  schema_transformations: Optional[
2418
2440
  List[
2419
2441
  Union[
@@ -2749,6 +2771,7 @@ class DynamicDeclarativeStream(BaseModel):
2749
2771
 
2750
2772
 
2751
2773
  ComplexFieldType.update_forward_refs()
2774
+ CombinedExtractor.update_forward_refs()
2752
2775
  GzipDecoder.update_forward_refs()
2753
2776
  CompositeErrorHandler.update_forward_refs()
2754
2777
  DeclarativeSource1.update_forward_refs()
@@ -83,7 +83,9 @@ from airbyte_cdk.sources.declarative.decoders.composite_raw_decoder import (
83
83
  Parser,
84
84
  )
85
85
  from airbyte_cdk.sources.declarative.extractors import (
86
+ CombinedExtractor,
86
87
  DpathExtractor,
88
+ KeyValueExtractor,
87
89
  RecordFilter,
88
90
  RecordSelector,
89
91
  ResponseToFileExtractor,
@@ -142,6 +144,9 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
142
144
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
143
145
  CheckStream as CheckStreamModel,
144
146
  )
147
+ from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
148
+ CombinedExtractor as CombinedExtractorModel,
149
+ )
145
150
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
146
151
  ComplexFieldType as ComplexFieldTypeModel,
147
152
  )
@@ -304,6 +309,9 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
304
309
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
305
310
  KeysToSnakeCase as KeysToSnakeCaseModel,
306
311
  )
312
+ from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
313
+ KeyValueExtractor as KeyValueExtractorModel,
314
+ )
307
315
  from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
308
316
  LegacySessionTokenAuthenticator as LegacySessionTokenAuthenticatorModel,
309
317
  )
@@ -641,6 +649,8 @@ class ModelToComponentFactory:
641
649
  DefaultErrorHandlerModel: self.create_default_error_handler,
642
650
  DefaultPaginatorModel: self.create_default_paginator,
643
651
  DpathExtractorModel: self.create_dpath_extractor,
652
+ KeyValueExtractorModel: self.create_key_value_extractor,
653
+ CombinedExtractorModel: self.create_combined_extractor,
644
654
  ResponseToFileExtractorModel: self.create_response_to_file_extractor,
645
655
  ExponentialBackoffStrategyModel: self.create_exponential_backoff_strategy,
646
656
  SessionTokenAuthenticatorModel: self.create_session_token_authenticator,
@@ -2218,6 +2228,36 @@ class ModelToComponentFactory:
2218
2228
  parameters=model.parameters or {},
2219
2229
  )
2220
2230
 
2231
+ def create_key_value_extractor(
2232
+ self,
2233
+ model: KeyValueExtractorModel,
2234
+ config: Config,
2235
+ decoder: Optional[Decoder] = JsonDecoder(parameters={}),
2236
+ **kwargs: Any,
2237
+ ) -> KeyValueExtractor:
2238
+ keys_extractor = self._create_component_from_model(
2239
+ model=model.keys_extractor, decoder=decoder, config=config
2240
+ )
2241
+ values_extractor = self._create_component_from_model(
2242
+ model=model.values_extractor, decoder=decoder, config=config
2243
+ )
2244
+
2245
+ return KeyValueExtractor(keys_extractor=keys_extractor, values_extractor=values_extractor)
2246
+
2247
+ def create_combined_extractor(
2248
+ self,
2249
+ model: CombinedExtractorModel,
2250
+ config: Config,
2251
+ decoder: Optional[Decoder] = JsonDecoder(parameters={}),
2252
+ **kwargs: Any,
2253
+ ) -> CombinedExtractor:
2254
+ extractors = [
2255
+ self._create_component_from_model(model=extractor, decoder=decoder, config=config)
2256
+ for extractor in model.extractors
2257
+ ]
2258
+
2259
+ return CombinedExtractor(extractors=extractors)
2260
+
2221
2261
  @staticmethod
2222
2262
  def create_response_to_file_extractor(
2223
2263
  model: ResponseToFileExtractorModel,
@@ -2432,10 +2472,14 @@ class ModelToComponentFactory:
2432
2472
  schema_type_identifier = self._create_component_from_model(
2433
2473
  model.schema_type_identifier, config=config, parameters=model.parameters or {}
2434
2474
  )
2475
+ schema_filter = self._create_component_from_model(
2476
+ model.schema_filter, config=config, parameters=model.parameters or {}
2477
+ )
2435
2478
  return DynamicSchemaLoader(
2436
2479
  retriever=retriever,
2437
2480
  config=config,
2438
2481
  schema_transformations=schema_transformations,
2482
+ schema_filter=schema_filter,
2439
2483
  schema_type_identifier=schema_type_identifier,
2440
2484
  parameters=model.parameters or {},
2441
2485
  )
@@ -3597,6 +3641,7 @@ class ModelToComponentFactory:
3597
3641
  field_path=field_path, # type: ignore[arg-type] # field_path can be str and InterpolatedString
3598
3642
  value=interpolated_value,
3599
3643
  value_type=ModelToComponentFactory._json_schema_type_name_to_type(model.value_type),
3644
+ create_or_update=model.create_or_update,
3600
3645
  parameters=model.parameters or {},
3601
3646
  )
3602
3647
 
@@ -3643,16 +3688,24 @@ class ModelToComponentFactory:
3643
3688
 
3644
3689
  return StreamConfig(
3645
3690
  configs_pointer=model_configs_pointer,
3691
+ default_values=model.default_values,
3646
3692
  parameters=model.parameters or {},
3647
3693
  )
3648
3694
 
3649
3695
  def create_config_components_resolver(
3650
3696
  self, model: ConfigComponentsResolverModel, config: Config
3651
3697
  ) -> Any:
3652
- stream_config = self._create_component_from_model(
3653
- model.stream_config, config=config, parameters=model.parameters or {}
3698
+ model_stream_configs = (
3699
+ model.stream_config if isinstance(model.stream_config, list) else [model.stream_config]
3654
3700
  )
3655
3701
 
3702
+ stream_configs = [
3703
+ self._create_component_from_model(
3704
+ stream_config, config=config, parameters=model.parameters or {}
3705
+ )
3706
+ for stream_config in model_stream_configs
3707
+ ]
3708
+
3656
3709
  components_mapping = [
3657
3710
  self._create_component_from_model(
3658
3711
  model=components_mapping_definition_model,
@@ -3665,7 +3718,7 @@ class ModelToComponentFactory:
3665
3718
  ]
3666
3719
 
3667
3720
  return ConfigComponentsResolver(
3668
- stream_config=stream_config,
3721
+ stream_configs=stream_configs,
3669
3722
  config=config,
3670
3723
  components_mapping=components_mapping,
3671
3724
  parameters=model.parameters or {},
@@ -22,6 +22,7 @@ class ComponentMappingDefinition:
22
22
  value: Union["InterpolatedString", str]
23
23
  value_type: Optional[Type[Any]]
24
24
  parameters: InitVar[Mapping[str, Any]]
25
+ create_or_update: Optional[bool] = False
25
26
 
26
27
 
27
28
  @dataclass(frozen=True)
@@ -34,6 +35,7 @@ class ResolvedComponentMappingDefinition:
34
35
  value: "InterpolatedString"
35
36
  value_type: Optional[Type[Any]]
36
37
  parameters: InitVar[Mapping[str, Any]]
38
+ create_or_update: Optional[bool] = False
37
39
 
38
40
 
39
41
  @deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning)
@@ -4,7 +4,8 @@
4
4
 
5
5
  from copy import deepcopy
6
6
  from dataclasses import InitVar, dataclass, field
7
- from typing import Any, Dict, Iterable, List, Mapping, Union
7
+ from itertools import product
8
+ from typing import Any, Dict, Iterable, List, Mapping, Optional, Union
8
9
 
9
10
  import dpath
10
11
  from typing_extensions import deprecated
@@ -28,6 +29,7 @@ class StreamConfig:
28
29
 
29
30
  configs_pointer: List[Union[InterpolatedString, str]]
30
31
  parameters: InitVar[Mapping[str, Any]]
32
+ default_values: Optional[List[Any]] = None
31
33
 
32
34
  def __post_init__(self, parameters: Mapping[str, Any]) -> None:
33
35
  self.configs_pointer = [
@@ -48,7 +50,7 @@ class ConfigComponentsResolver(ComponentsResolver):
48
50
  parameters (InitVar[Mapping[str, Any]]): Additional parameters for interpolation.
49
51
  """
50
52
 
51
- stream_config: StreamConfig
53
+ stream_configs: List[StreamConfig]
52
54
  config: Config
53
55
  components_mapping: List[ComponentMappingDefinition]
54
56
  parameters: InitVar[Mapping[str, Any]]
@@ -82,6 +84,7 @@ class ConfigComponentsResolver(ComponentsResolver):
82
84
  field_path=field_path,
83
85
  value=interpolated_value,
84
86
  value_type=component_mapping.value_type,
87
+ create_or_update=component_mapping.create_or_update,
85
88
  parameters=parameters,
86
89
  )
87
90
  )
@@ -91,17 +94,35 @@ class ConfigComponentsResolver(ComponentsResolver):
91
94
  )
92
95
 
93
96
  @property
94
- def _stream_config(self) -> Iterable[Mapping[str, Any]]:
95
- path = [
96
- node.eval(self.config) if not isinstance(node, str) else node
97
- for node in self.stream_config.configs_pointer
98
- ]
99
- stream_config = dpath.get(dict(self.config), path, default=[])
100
-
101
- if not isinstance(stream_config, list):
102
- stream_config = [stream_config]
103
-
104
- return stream_config
97
+ def _stream_config(self):
98
+ def resolve_path(pointer):
99
+ return [
100
+ node.eval(self.config) if not isinstance(node, str) else node for node in pointer
101
+ ]
102
+
103
+ def normalize_configs(configs):
104
+ return configs if isinstance(configs, list) else [configs]
105
+
106
+ def prepare_streams():
107
+ for stream_config in self.stream_configs:
108
+ path = resolve_path(stream_config.configs_pointer)
109
+ stream_configs = dpath.get(dict(self.config), path, default=[])
110
+ stream_configs = normalize_configs(stream_configs)
111
+ if stream_config.default_values:
112
+ stream_configs += stream_config.default_values
113
+ yield [(i, item) for i, item in enumerate(stream_configs)]
114
+
115
+ def merge_combination(combo):
116
+ result = {}
117
+ for config_index, (elem_index, elem) in enumerate(combo):
118
+ if isinstance(elem, dict):
119
+ result.update(elem)
120
+ else:
121
+ result.setdefault(f"source_config_{config_index}", (elem_index, elem))
122
+ return result
123
+
124
+ all_indexed_streams = list(prepare_streams())
125
+ return [merge_combination(combo) for combo in product(*all_indexed_streams)]
105
126
 
106
127
  def resolve_components(
107
128
  self, stream_template_config: Dict[str, Any]
@@ -130,7 +151,21 @@ class ConfigComponentsResolver(ComponentsResolver):
130
151
  )
131
152
 
132
153
  path = [path.eval(self.config, **kwargs) for path in resolved_component.field_path]
154
+ parsed_value = self._parse_yaml_if_possible(value)
155
+ updated = dpath.set(updated_config, path, parsed_value)
133
156
 
134
- dpath.set(updated_config, path, value)
157
+ if parsed_value and not updated and resolved_component.create_or_update:
158
+ dpath.new(updated_config, path, parsed_value)
135
159
 
136
160
  yield updated_config
161
+
162
+ @staticmethod
163
+ def _parse_yaml_if_possible(value: Any) -> Any:
164
+ if isinstance(value, str):
165
+ try:
166
+ import yaml
167
+
168
+ return yaml.safe_load(value)
169
+ except Exception:
170
+ return value
171
+ return value
@@ -10,6 +10,7 @@ from typing import Any, List, Mapping, MutableMapping, Optional, Union
10
10
  import dpath
11
11
  from typing_extensions import deprecated
12
12
 
13
+ from airbyte_cdk.sources.declarative.extractors.record_filter import RecordFilter
13
14
  from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean
14
15
  from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
15
16
  from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever
@@ -126,6 +127,7 @@ class DynamicSchemaLoader(SchemaLoader):
126
127
  parameters: InitVar[Mapping[str, Any]]
127
128
  schema_type_identifier: SchemaTypeIdentifier
128
129
  schema_transformations: List[RecordTransformation] = field(default_factory=lambda: [])
130
+ schema_filter: Optional[RecordFilter] = None
129
131
 
130
132
  def get_json_schema(self) -> Mapping[str, Any]:
131
133
  """
@@ -151,20 +153,18 @@ class DynamicSchemaLoader(SchemaLoader):
151
153
  )
152
154
  properties[key] = value
153
155
 
154
- transformed_properties = self._transform(properties, {})
156
+ filtred_transformed_properties = self._transform(self._filter(properties))
155
157
 
156
158
  return {
157
159
  "$schema": "https://json-schema.org/draft-07/schema#",
158
160
  "type": "object",
159
161
  "additionalProperties": True,
160
- "properties": transformed_properties,
162
+ "properties": filtred_transformed_properties,
161
163
  }
162
164
 
163
165
  def _transform(
164
166
  self,
165
167
  properties: Mapping[str, Any],
166
- stream_state: StreamState,
167
- stream_slice: Optional[StreamSlice] = None,
168
168
  ) -> Mapping[str, Any]:
169
169
  for transformation in self.schema_transformations:
170
170
  transformation.transform(
@@ -173,6 +173,21 @@ class DynamicSchemaLoader(SchemaLoader):
173
173
  )
174
174
  return properties
175
175
 
176
+ def _filter(
177
+ self,
178
+ properties: Mapping[str, Any],
179
+ ) -> Mapping[str, Any]:
180
+ if not self.schema_filter:
181
+ return properties
182
+
183
+ filtered_properties = {}
184
+ for item in self.schema_filter.filter_records(
185
+ ({k: v} for k, v in properties.items()),
186
+ {},
187
+ ):
188
+ filtered_properties.update(item)
189
+ return filtered_properties
190
+
176
191
  def _get_key(
177
192
  self,
178
193
  raw_schema: MutableMapping[str, Any],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-cdk
3
- Version: 6.48.15
3
+ Version: 6.48.17.dev0
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  Home-page: https://airbyte.com
6
6
  License: MIT
@@ -1,10 +1,10 @@
1
1
  airbyte_cdk/__init__.py,sha256=52uncJvDQNHvwKxaqzXgnMYTptIl65LDJr2fvlk8-DU,11707
2
2
  airbyte_cdk/cli/__init__.py,sha256=CXsai3MYMLZ_sqi2vPAIVcKDun8VRqlv0cKffBI0iSY,346
3
3
  airbyte_cdk/cli/airbyte_cdk/__init__.py,sha256=8IoEcbdYr7CMAh97Xut5__uHH9vV4LKUtSBNTk3qEWY,2031
4
- airbyte_cdk/cli/airbyte_cdk/_connector.py,sha256=drKb_EXJOFX-cSeLwJB8WXE-lesOL0dx2ziWSmW3Jkg,5187
4
+ airbyte_cdk/cli/airbyte_cdk/_connector.py,sha256=PA1beSvhcvm-6watFCrjNat9GC4RpYolC53z2r1V3dc,5234
5
5
  airbyte_cdk/cli/airbyte_cdk/_image.py,sha256=AkBEZrRYXEwvhW7hPOPRWeYEZutzi2PIzjpl7_yaE8I,2890
6
6
  airbyte_cdk/cli/airbyte_cdk/_manifest.py,sha256=aFdeeWgek7oXR3YfZPxk7kBZ64Blmsr0dAXN6BVGiIA,482
7
- airbyte_cdk/cli/airbyte_cdk/_secrets.py,sha256=1IqVz-csoMJoKajSX4DzoWrngswuNHBPkzzchQggAeE,17010
7
+ airbyte_cdk/cli/airbyte_cdk/_secrets.py,sha256=jLtpkhFJHavABN3UuqddeDRGS8v1iEj0e_f6WTeYoQA,17409
8
8
  airbyte_cdk/cli/airbyte_cdk/_version.py,sha256=ohZNIktLFk91sdzqFW5idaNrZAPX2dIRnz---_fcKOE,352
9
9
  airbyte_cdk/cli/airbyte_cdk/exceptions.py,sha256=bsGmlWN6cXL2jCD1WYAZMqFmK1OLg2xLrcC_60KHSeA,803
10
10
  airbyte_cdk/cli/source_declarative_manifest/__init__.py,sha256=-0ST722Nj65bgRokzpzPkD1NBBW5CytEHFUe38cB86Q,91
@@ -89,7 +89,7 @@ airbyte_cdk/sources/declarative/concurrent_declarative_source.py,sha256=GoZJ8Oxb
89
89
  airbyte_cdk/sources/declarative/datetime/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
90
90
  airbyte_cdk/sources/declarative/datetime/datetime_parser.py,sha256=_zGNGq31RNy_0QBLt_EcTvgPyhj7urPdx6oA3M5-r3o,3150
91
91
  airbyte_cdk/sources/declarative/datetime/min_max_datetime.py,sha256=0BHBtDNQZfvwM45-tY5pNlTcKAFSGGNxemoi0Jic-0E,5785
92
- airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=7tB0-d4lbI97GB5lBI6-qezxLoKZN4QeN_4Vht9TDFo,167270
92
+ airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=o3t_npbhuPBKJ4PCTYz0zh3XT6AtpDMhe8TMujPYCUs,169241
93
93
  airbyte_cdk/sources/declarative/declarative_source.py,sha256=qmyMnnet92eGc3C22yBtpvD5UZjqdhsAafP_zxI5wp8,1814
94
94
  airbyte_cdk/sources/declarative/declarative_stream.py,sha256=dCRlddBUSaJmBNBz1pSO1r2rTw8AP5d2_vlmIeGs2gg,10767
95
95
  airbyte_cdk/sources/declarative/decoders/__init__.py,sha256=JHb_0d3SE6kNY10mxA5YBEKPeSbsWYjByq1gUQxepoE,953
@@ -102,9 +102,11 @@ airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py,sha256=
102
102
  airbyte_cdk/sources/declarative/decoders/xml_decoder.py,sha256=EU-7t-5vIGRHZ14h-f0GUE4V5-eTM9Flux-A8xgI1Rc,3117
103
103
  airbyte_cdk/sources/declarative/decoders/zipfile_decoder.py,sha256=Din18m61aly2oG6TaXGpLcbfUHVOzjGzuMYkyxfHXT4,2290
104
104
  airbyte_cdk/sources/declarative/exceptions.py,sha256=kTPUA4I2NV4J6HDz-mKPGMrfuc592akJnOyYx38l_QM,176
105
- airbyte_cdk/sources/declarative/extractors/__init__.py,sha256=RmV-IkO1YLj0PSOrrqC9AV1gO8-90t8UTDVfJGshN9E,754
105
+ airbyte_cdk/sources/declarative/extractors/__init__.py,sha256=3Cu6FduH2FmWigvMAMd03o_ZfOSoUFLSb3BBfoc1xW4,989
106
+ airbyte_cdk/sources/declarative/extractors/combined_extractor.py,sha256=_yM2eywOYYXDkONPssGU6JkEJlc81-cfamiEw7t_suk,1603
106
107
  airbyte_cdk/sources/declarative/extractors/dpath_extractor.py,sha256=wR4Ol4MG2lt5UlqXF5EU_k7qa5cN4_-luu3PJ1PlO3A,3131
107
108
  airbyte_cdk/sources/declarative/extractors/http_selector.py,sha256=2zWZ4ewTqQC8VwkjS0xD_u350Km3SiYP7hpOOgiLg5o,1169
109
+ airbyte_cdk/sources/declarative/extractors/key_value_extractor.py,sha256=wmAr5RqOQXHsqhHDOwAIhPZZSRYm_NnPn3xTxl3oHyM,1641
108
110
  airbyte_cdk/sources/declarative/extractors/record_extractor.py,sha256=XJELMjahAsaomlvQgN2zrNO0DJX0G0fr9r682gUz7Pg,691
109
111
  airbyte_cdk/sources/declarative/extractors/record_filter.py,sha256=yTdEkyDUSW2KbFkEwJJMlS963C955LgCCOVfTmmScpQ,3367
110
112
  airbyte_cdk/sources/declarative/extractors/record_selector.py,sha256=vCpwX1PVRFPYKMzm0DHHP3YEZ0Gmd3bBzggOsRha038,7192
@@ -127,20 +129,20 @@ airbyte_cdk/sources/declarative/interpolation/interpolated_string.py,sha256=CQkH
127
129
  airbyte_cdk/sources/declarative/interpolation/interpolation.py,sha256=9IoeuWam3L6GyN10L6U8xNWXmkt9cnahSDNkez1OmFY,982
128
130
  airbyte_cdk/sources/declarative/interpolation/jinja.py,sha256=UQeuS4Vpyp4hlOn-R3tRyeBX0e9IoV6jQ6gH-Jz8lY0,7182
129
131
  airbyte_cdk/sources/declarative/interpolation/macros.py,sha256=UYSJ5gW7TkHALYnNvUnRP3RlyGwGuRMObF3BHuNzjJM,5320
130
- airbyte_cdk/sources/declarative/manifest_declarative_source.py,sha256=cZNUOeIogrCmCS7RXeJqQIlnsANigz1cngpLko02M2g,23191
132
+ airbyte_cdk/sources/declarative/manifest_declarative_source.py,sha256=88uuVKamdAFzsC3JBKvajI8icZj00BmRLFQe9bFskrk,23132
131
133
  airbyte_cdk/sources/declarative/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
134
  airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py,sha256=V2lpYE9LJKvz6BUViHk4vaRGndxNABmPbDCtyYdkqaE,4013
133
135
  airbyte_cdk/sources/declarative/migrations/state_migration.py,sha256=KWPjealMLKSMtajXgkdGgKg7EmTLR-CqqD7UIh0-eDU,794
134
136
  airbyte_cdk/sources/declarative/models/__init__.py,sha256=nUFxNCiKeYRVXuZEKA7GD-lTHxsiKcQ8FitZjKhPIvE,100
135
137
  airbyte_cdk/sources/declarative/models/base_model_with_deprecations.py,sha256=Imnj3yef0aqRdLfaUxkIYISUb8YkiPrRH_wBd-x8HjM,5999
136
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=FjZ2WrItKCqMVxc14XRbMPu11Jhl1Ds3Lugy_2wPoQ8,118235
138
+ airbyte_cdk/sources/declarative/models/declarative_component_schema.py,sha256=8La2uX0ODkXwBW1PXkHpg-EkSwttf_nDSXYq9BiPKVo,119463
137
139
  airbyte_cdk/sources/declarative/parsers/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
138
140
  airbyte_cdk/sources/declarative/parsers/custom_code_compiler.py,sha256=nlVvHC511NUyDEEIRBkoeDTAvLqKNp-hRy8D19z8tdk,5941
139
141
  airbyte_cdk/sources/declarative/parsers/custom_exceptions.py,sha256=wnRUP0Xeru9Rbu5OexXSDN9QWDo8YU4tT9M2LDVOgGA,802
140
142
  airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py,sha256=2UdpCz3yi7ISZTyqkQXSSy3dMxeyOWqV7OlAS5b9GVg,11568
141
143
  airbyte_cdk/sources/declarative/parsers/manifest_normalizer.py,sha256=laBy7ebjA-PiNwc-50U4FHvMqS_mmHvnabxgFs4CjGw,17069
142
144
  airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py,sha256=pJmg78vqE5VfUrF_KJnWjucQ4k9IWFULeAxHCowrHXE,6806
143
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=uPefJHWYdLxupSVqI4_VnU30JlbA44EQ7GwY0RdfaVw,168443
145
+ airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=ZUEh2-mIuhLBjZrECyZB54K-S402sjHDXIUcJ1Cwy18,170489
144
146
  airbyte_cdk/sources/declarative/partition_routers/__init__.py,sha256=TBC9AkGaUqHm2IKHMPN6punBIcY5tWGULowcLoAVkfw,1109
145
147
  airbyte_cdk/sources/declarative/partition_routers/async_job_partition_router.py,sha256=VelO7zKqKtzMJ35jyFeg0ypJLQC0plqqIBNXoBW1G2E,3001
146
148
  airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py,sha256=c5cuVFM6NFkuQqG8Z5IwkBuwDrvXZN1CunUOM_L0ezg,6892
@@ -194,8 +196,8 @@ airbyte_cdk/sources/declarative/requesters/request_options/request_options_provi
194
196
  airbyte_cdk/sources/declarative/requesters/request_path.py,sha256=S3MeFvcaQrMbOkSY2W2VbXLNomqt_3eXqVd9ZhgNwUs,299
195
197
  airbyte_cdk/sources/declarative/requesters/requester.py,sha256=T6tMx_Bx4iT-0YVjY7IzgRil-gaIu9n01b1iwpTh3Ek,5516
196
198
  airbyte_cdk/sources/declarative/resolvers/__init__.py,sha256=NiDcz5qi8HPsfX94MUmnX0Rgs_kQXGvucOmJjNWlxKQ,1207
197
- airbyte_cdk/sources/declarative/resolvers/components_resolver.py,sha256=KPjKc0yb9artL4ZkeqN8RmEykHH6FJgqXD7fCEnh1X0,1936
198
- airbyte_cdk/sources/declarative/resolvers/config_components_resolver.py,sha256=dz4iJV9liD_LzY_Mn4XmAStoUll60R3MIGWV4aN3pgg,5223
199
+ airbyte_cdk/sources/declarative/resolvers/components_resolver.py,sha256=oJIpy66ep8n-QOc8GwpllApTRcl4QtQhkTw5fWWra2w,2026
200
+ airbyte_cdk/sources/declarative/resolvers/config_components_resolver.py,sha256=1coEpB_mRAV1NgoaWd4CMllf4SPOFQGi3ac3DTP71ZQ,6791
199
201
  airbyte_cdk/sources/declarative/resolvers/http_components_resolver.py,sha256=AiojNs8wItJFrENZBFUaDvau3sgwudO6Wkra36upSPo,4639
200
202
  airbyte_cdk/sources/declarative/retrievers/__init__.py,sha256=nQepwG_RfW53sgwvK5dLPqfCx0VjsQ83nYoPjBMAaLM,527
201
203
  airbyte_cdk/sources/declarative/retrievers/async_retriever.py,sha256=6oZtnCHm9NdDvjTSrVwPQOXGSdETSIR7eWH2vFjM7jI,4855
@@ -211,7 +213,7 @@ airbyte_cdk/sources/declarative/retrievers/simple_retriever.py,sha256=Ui7V_etQ-s
211
213
  airbyte_cdk/sources/declarative/schema/__init__.py,sha256=xU45UvM5O4c1PSM13UHpCdh5hpW3HXy9vRRGEiAC1rg,795
212
214
  airbyte_cdk/sources/declarative/schema/composite_schema_loader.py,sha256=ymGbvxS_QyGc4nnjEyRo5ch8bVedELO41PAUxKXZyMw,1113
213
215
  airbyte_cdk/sources/declarative/schema/default_schema_loader.py,sha256=UnbzlExmwoQiVV8zDg4lhAEaqA_0pRfwbMRe8yqOuWk,1834
214
- airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py,sha256=J8Q_iJYhcSQLWyt0bTZCbDAGpxt9G8FCc6Q9jtGsNzw,10703
216
+ airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py,sha256=q_AUnbzm6AoZd31NhlU4ucTkwRwEqE5VvVeXqKLYfrM,11186
215
217
  airbyte_cdk/sources/declarative/schema/inline_schema_loader.py,sha256=bVETE10hRsatRJq3R3BeyRR0wIoK3gcP1gcpVRQ_P5U,464
216
218
  airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py,sha256=5Wl-fqW-pVf_dxJ4yGHMAFfC4JjKHYJhqFJT1xA57F4,4177
217
219
  airbyte_cdk/sources/declarative/schema/schema_loader.py,sha256=kjt8v0N5wWKA5zyLnrDLxf1PJKdUqvQq2RVnAOAzNSY,379
@@ -419,9 +421,9 @@ airbyte_cdk/utils/slice_hasher.py,sha256=EDxgROHDbfG-QKQb59m7h_7crN1tRiawdf5uU7G
419
421
  airbyte_cdk/utils/spec_schema_transformations.py,sha256=-5HTuNsnDBAhj-oLeQXwpTGA0HdcjFOf2zTEMUTTg_Y,816
420
422
  airbyte_cdk/utils/stream_status_utils.py,sha256=ZmBoiy5HVbUEHAMrUONxZvxnvfV9CesmQJLDTAIWnWw,1171
421
423
  airbyte_cdk/utils/traced_exception.py,sha256=C8uIBuCL_E4WnBAOPSxBicD06JAldoN9fGsQDp463OY,6292
422
- airbyte_cdk-6.48.15.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
423
- airbyte_cdk-6.48.15.dist-info/LICENSE_SHORT,sha256=aqF6D1NcESmpn-cqsxBtszTEnHKnlsp8L4x9wAh3Nxg,55
424
- airbyte_cdk-6.48.15.dist-info/METADATA,sha256=DP9YSnAFjf7aaIFb4V1xGPe6kc3TY8HAQNZdy7Bgaq4,6344
425
- airbyte_cdk-6.48.15.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
426
- airbyte_cdk-6.48.15.dist-info/entry_points.txt,sha256=AKWbEkHfpzzk9nF9tqBUaw1MbvTM4mGtEzmZQm0ZWvM,139
427
- airbyte_cdk-6.48.15.dist-info/RECORD,,
424
+ airbyte_cdk-6.48.17.dev0.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
425
+ airbyte_cdk-6.48.17.dev0.dist-info/LICENSE_SHORT,sha256=aqF6D1NcESmpn-cqsxBtszTEnHKnlsp8L4x9wAh3Nxg,55
426
+ airbyte_cdk-6.48.17.dev0.dist-info/METADATA,sha256=rybxpJSXyko7F2tXrJGvD79wVY9N0ie5ibd0CXaNE8w,6349
427
+ airbyte_cdk-6.48.17.dev0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
428
+ airbyte_cdk-6.48.17.dev0.dist-info/entry_points.txt,sha256=AKWbEkHfpzzk9nF9tqBUaw1MbvTM4mGtEzmZQm0ZWvM,139
429
+ airbyte_cdk-6.48.17.dev0.dist-info/RECORD,,