airbyte-cdk 6.48.17.dev0__py3-none-any.whl → 6.49.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airbyte_cdk/cli/source_declarative_manifest/_run.py +69 -10
- airbyte_cdk/connector.py +3 -3
- airbyte_cdk/entrypoint.py +36 -0
- airbyte_cdk/sources/declarative/declarative_component_schema.yaml +277 -69
- airbyte_cdk/sources/declarative/extractors/__init__.py +0 -4
- airbyte_cdk/sources/declarative/manifest_declarative_source.py +3 -1
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py +190 -45
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +155 -60
- airbyte_cdk/sources/declarative/resolvers/components_resolver.py +0 -2
- airbyte_cdk/sources/declarative/resolvers/config_components_resolver.py +14 -49
- airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py +4 -19
- airbyte_cdk/sources/declarative/spec/__init__.py +2 -2
- airbyte_cdk/sources/declarative/spec/spec.py +71 -2
- airbyte_cdk/sources/declarative/transformations/config_transformations/add_fields.py +10 -23
- airbyte_cdk/sources/declarative/transformations/config_transformations/remap_field.py +2 -3
- airbyte_cdk/sources/declarative/validators/dpath_validator.py +1 -1
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/METADATA +1 -1
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/RECORD +22 -24
- airbyte_cdk/sources/declarative/extractors/combined_extractor.py +0 -44
- airbyte_cdk/sources/declarative/extractors/key_value_extractor.py +0 -46
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/LICENSE.txt +0 -0
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/LICENSE_SHORT +0 -0
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/WHEEL +0 -0
- {airbyte_cdk-6.48.17.dev0.dist-info → airbyte_cdk-6.49.1.dist-info}/entry_points.txt +0 -0
@@ -19,6 +19,7 @@ from typing import (
|
|
19
19
|
Optional,
|
20
20
|
Type,
|
21
21
|
Union,
|
22
|
+
cast,
|
22
23
|
get_args,
|
23
24
|
get_origin,
|
24
25
|
get_type_hints,
|
@@ -33,6 +34,7 @@ from airbyte_cdk.connector_builder.models import (
|
|
33
34
|
)
|
34
35
|
from airbyte_cdk.models import FailureType, Level
|
35
36
|
from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager
|
37
|
+
from airbyte_cdk.sources.declarative import transformations
|
36
38
|
from airbyte_cdk.sources.declarative.async_job.job_orchestrator import AsyncJobOrchestrator
|
37
39
|
from airbyte_cdk.sources.declarative.async_job.job_tracker import JobTracker
|
38
40
|
from airbyte_cdk.sources.declarative.async_job.repository import AsyncJobRepository
|
@@ -83,9 +85,7 @@ from airbyte_cdk.sources.declarative.decoders.composite_raw_decoder import (
|
|
83
85
|
Parser,
|
84
86
|
)
|
85
87
|
from airbyte_cdk.sources.declarative.extractors import (
|
86
|
-
CombinedExtractor,
|
87
88
|
DpathExtractor,
|
88
|
-
KeyValueExtractor,
|
89
89
|
RecordFilter,
|
90
90
|
RecordSelector,
|
91
91
|
ResponseToFileExtractor,
|
@@ -144,9 +144,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
144
144
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
145
145
|
CheckStream as CheckStreamModel,
|
146
146
|
)
|
147
|
-
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
148
|
-
CombinedExtractor as CombinedExtractorModel,
|
149
|
-
)
|
150
147
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
151
148
|
ComplexFieldType as ComplexFieldTypeModel,
|
152
149
|
)
|
@@ -159,9 +156,21 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
159
156
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
160
157
|
ConcurrencyLevel as ConcurrencyLevelModel,
|
161
158
|
)
|
159
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
160
|
+
ConfigAddFields as ConfigAddFieldsModel,
|
161
|
+
)
|
162
162
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
163
163
|
ConfigComponentsResolver as ConfigComponentsResolverModel,
|
164
164
|
)
|
165
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
166
|
+
ConfigMigration as ConfigMigrationModel,
|
167
|
+
)
|
168
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
169
|
+
ConfigRemapField as ConfigRemapFieldModel,
|
170
|
+
)
|
171
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
172
|
+
ConfigRemoveFields as ConfigRemoveFieldsModel,
|
173
|
+
)
|
165
174
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
166
175
|
ConstantBackoffStrategy as ConstantBackoffStrategyModel,
|
167
176
|
)
|
@@ -231,6 +240,9 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
231
240
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
232
241
|
DpathFlattenFields as DpathFlattenFieldsModel,
|
233
242
|
)
|
243
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
244
|
+
DpathValidator as DpathValidatorModel,
|
245
|
+
)
|
234
246
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
235
247
|
DynamicSchemaLoader as DynamicSchemaLoaderModel,
|
236
248
|
)
|
@@ -309,9 +321,6 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
309
321
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
310
322
|
KeysToSnakeCase as KeysToSnakeCaseModel,
|
311
323
|
)
|
312
|
-
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
313
|
-
KeyValueExtractor as KeyValueExtractorModel,
|
314
|
-
)
|
315
324
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
316
325
|
LegacySessionTokenAuthenticator as LegacySessionTokenAuthenticatorModel,
|
317
326
|
)
|
@@ -345,6 +354,9 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
345
354
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
346
355
|
ParentStreamConfig as ParentStreamConfigModel,
|
347
356
|
)
|
357
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
358
|
+
PredicateValidator as PredicateValidatorModel,
|
359
|
+
)
|
348
360
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
349
361
|
PropertiesFromEndpoint as PropertiesFromEndpointModel,
|
350
362
|
)
|
@@ -409,6 +421,9 @@ from airbyte_cdk.sources.declarative.models.declarative_component_schema import
|
|
409
421
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
410
422
|
UnlimitedCallRatePolicy as UnlimitedCallRatePolicyModel,
|
411
423
|
)
|
424
|
+
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
425
|
+
ValidateAdheresToSchema as ValidateAdheresToSchemaModel,
|
426
|
+
)
|
412
427
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import ValueType
|
413
428
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import (
|
414
429
|
WaitTimeFromHeader as WaitTimeFromHeaderModel,
|
@@ -484,7 +499,7 @@ from airbyte_cdk.sources.declarative.requesters.request_options import (
|
|
484
499
|
RequestOptionsProvider,
|
485
500
|
)
|
486
501
|
from airbyte_cdk.sources.declarative.requesters.request_path import RequestPath
|
487
|
-
from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod
|
502
|
+
from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod, Requester
|
488
503
|
from airbyte_cdk.sources.declarative.resolvers import (
|
489
504
|
ComponentMappingDefinition,
|
490
505
|
ConfigComponentsResolver,
|
@@ -514,7 +529,7 @@ from airbyte_cdk.sources.declarative.schema import (
|
|
514
529
|
TypesMap,
|
515
530
|
)
|
516
531
|
from airbyte_cdk.sources.declarative.schema.composite_schema_loader import CompositeSchemaLoader
|
517
|
-
from airbyte_cdk.sources.declarative.spec import Spec
|
532
|
+
from airbyte_cdk.sources.declarative.spec import ConfigMigration, Spec
|
518
533
|
from airbyte_cdk.sources.declarative.stream_slicers import StreamSlicer
|
519
534
|
from airbyte_cdk.sources.declarative.transformations import (
|
520
535
|
AddFields,
|
@@ -522,6 +537,14 @@ from airbyte_cdk.sources.declarative.transformations import (
|
|
522
537
|
RemoveFields,
|
523
538
|
)
|
524
539
|
from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition
|
540
|
+
from airbyte_cdk.sources.declarative.transformations.config_transformations import (
|
541
|
+
ConfigAddFields,
|
542
|
+
ConfigRemapField,
|
543
|
+
ConfigRemoveFields,
|
544
|
+
)
|
545
|
+
from airbyte_cdk.sources.declarative.transformations.config_transformations.config_transformation import (
|
546
|
+
ConfigTransformation,
|
547
|
+
)
|
525
548
|
from airbyte_cdk.sources.declarative.transformations.dpath_flatten_fields import (
|
526
549
|
DpathFlattenFields,
|
527
550
|
KeyTransformation,
|
@@ -538,6 +561,11 @@ from airbyte_cdk.sources.declarative.transformations.keys_to_lower_transformatio
|
|
538
561
|
from airbyte_cdk.sources.declarative.transformations.keys_to_snake_transformation import (
|
539
562
|
KeysToSnakeCaseTransformation,
|
540
563
|
)
|
564
|
+
from airbyte_cdk.sources.declarative.validators import (
|
565
|
+
DpathValidator,
|
566
|
+
PredicateValidator,
|
567
|
+
ValidateAdheresToSchema,
|
568
|
+
)
|
541
569
|
from airbyte_cdk.sources.http_logger import format_http_message
|
542
570
|
from airbyte_cdk.sources.message import (
|
543
571
|
InMemoryMessageRepository,
|
@@ -626,6 +654,10 @@ class ModelToComponentFactory:
|
|
626
654
|
CheckDynamicStreamModel: self.create_check_dynamic_stream,
|
627
655
|
CompositeErrorHandlerModel: self.create_composite_error_handler,
|
628
656
|
ConcurrencyLevelModel: self.create_concurrency_level,
|
657
|
+
ConfigMigrationModel: self.create_config_migration,
|
658
|
+
ConfigAddFieldsModel: self.create_config_add_fields,
|
659
|
+
ConfigRemapFieldModel: self.create_config_remap_field,
|
660
|
+
ConfigRemoveFieldsModel: self.create_config_remove_fields,
|
629
661
|
ConstantBackoffStrategyModel: self.create_constant_backoff_strategy,
|
630
662
|
CsvDecoderModel: self.create_csv_decoder,
|
631
663
|
CursorPaginationModel: self.create_cursor_pagination,
|
@@ -649,8 +681,7 @@ class ModelToComponentFactory:
|
|
649
681
|
DefaultErrorHandlerModel: self.create_default_error_handler,
|
650
682
|
DefaultPaginatorModel: self.create_default_paginator,
|
651
683
|
DpathExtractorModel: self.create_dpath_extractor,
|
652
|
-
|
653
|
-
CombinedExtractorModel: self.create_combined_extractor,
|
684
|
+
DpathValidatorModel: self.create_dpath_validator,
|
654
685
|
ResponseToFileExtractorModel: self.create_response_to_file_extractor,
|
655
686
|
ExponentialBackoffStrategyModel: self.create_exponential_backoff_strategy,
|
656
687
|
SessionTokenAuthenticatorModel: self.create_session_token_authenticator,
|
@@ -684,6 +715,7 @@ class ModelToComponentFactory:
|
|
684
715
|
OffsetIncrementModel: self.create_offset_increment,
|
685
716
|
PageIncrementModel: self.create_page_increment,
|
686
717
|
ParentStreamConfigModel: self.create_parent_stream_config,
|
718
|
+
PredicateValidatorModel: self.create_predicate_validator,
|
687
719
|
PropertiesFromEndpointModel: self.create_properties_from_endpoint,
|
688
720
|
PropertyChunkingModel: self.create_property_chunking,
|
689
721
|
QueryPropertiesModel: self.create_query_properties,
|
@@ -698,6 +730,7 @@ class ModelToComponentFactory:
|
|
698
730
|
StateDelegatingStreamModel: self.create_state_delegating_stream,
|
699
731
|
SpecModel: self.create_spec,
|
700
732
|
SubstreamPartitionRouterModel: self.create_substream_partition_router,
|
733
|
+
ValidateAdheresToSchemaModel: self.create_validate_adheres_to_schema,
|
701
734
|
WaitTimeFromHeaderModel: self.create_wait_time_from_header,
|
702
735
|
WaitUntilTimeFromHeaderModel: self.create_wait_until_time_from_header,
|
703
736
|
AsyncRetrieverModel: self.create_async_retriever,
|
@@ -790,6 +823,75 @@ class ModelToComponentFactory:
|
|
790
823
|
if log not in self._collected_deprecation_logs:
|
791
824
|
self._collected_deprecation_logs.append(log)
|
792
825
|
|
826
|
+
def create_config_migration(
|
827
|
+
self, model: ConfigMigrationModel, config: Config
|
828
|
+
) -> ConfigMigration:
|
829
|
+
transformations: List[ConfigTransformation] = [
|
830
|
+
self._create_component_from_model(transformation, config)
|
831
|
+
for transformation in model.transformations
|
832
|
+
]
|
833
|
+
|
834
|
+
return ConfigMigration(
|
835
|
+
description=model.description,
|
836
|
+
transformations=transformations,
|
837
|
+
)
|
838
|
+
|
839
|
+
def create_config_add_fields(
|
840
|
+
self, model: ConfigAddFieldsModel, config: Config, **kwargs: Any
|
841
|
+
) -> ConfigAddFields:
|
842
|
+
fields = [self._create_component_from_model(field, config) for field in model.fields]
|
843
|
+
return ConfigAddFields(
|
844
|
+
fields=fields,
|
845
|
+
condition=model.condition or "",
|
846
|
+
)
|
847
|
+
|
848
|
+
@staticmethod
|
849
|
+
def create_config_remove_fields(
|
850
|
+
model: ConfigRemoveFieldsModel, config: Config, **kwargs: Any
|
851
|
+
) -> ConfigRemoveFields:
|
852
|
+
return ConfigRemoveFields(
|
853
|
+
field_pointers=model.field_pointers,
|
854
|
+
condition=model.condition or "",
|
855
|
+
)
|
856
|
+
|
857
|
+
@staticmethod
|
858
|
+
def create_config_remap_field(
|
859
|
+
model: ConfigRemapFieldModel, config: Config, **kwargs: Any
|
860
|
+
) -> ConfigRemapField:
|
861
|
+
mapping = cast(Mapping[str, Any], model.map)
|
862
|
+
return ConfigRemapField(
|
863
|
+
map=mapping,
|
864
|
+
field_path=model.field_path,
|
865
|
+
config=config,
|
866
|
+
)
|
867
|
+
|
868
|
+
def create_dpath_validator(self, model: DpathValidatorModel, config: Config) -> DpathValidator:
|
869
|
+
strategy = self._create_component_from_model(model.validation_strategy, config)
|
870
|
+
|
871
|
+
return DpathValidator(
|
872
|
+
field_path=model.field_path,
|
873
|
+
strategy=strategy,
|
874
|
+
)
|
875
|
+
|
876
|
+
def create_predicate_validator(
|
877
|
+
self, model: PredicateValidatorModel, config: Config
|
878
|
+
) -> PredicateValidator:
|
879
|
+
strategy = self._create_component_from_model(model.validation_strategy, config)
|
880
|
+
|
881
|
+
return PredicateValidator(
|
882
|
+
value=model.value,
|
883
|
+
strategy=strategy,
|
884
|
+
)
|
885
|
+
|
886
|
+
@staticmethod
|
887
|
+
def create_validate_adheres_to_schema(
|
888
|
+
model: ValidateAdheresToSchemaModel, config: Config, **kwargs: Any
|
889
|
+
) -> ValidateAdheresToSchema:
|
890
|
+
base_schema = cast(Mapping[str, Any], model.base_schema)
|
891
|
+
return ValidateAdheresToSchema(
|
892
|
+
schema=base_schema,
|
893
|
+
)
|
894
|
+
|
793
895
|
@staticmethod
|
794
896
|
def create_added_field_definition(
|
795
897
|
model: AddedFieldDefinitionModel, config: Config, **kwargs: Any
|
@@ -2228,36 +2330,6 @@ class ModelToComponentFactory:
|
|
2228
2330
|
parameters=model.parameters or {},
|
2229
2331
|
)
|
2230
2332
|
|
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
|
-
|
2261
2333
|
@staticmethod
|
2262
2334
|
def create_response_to_file_extractor(
|
2263
2335
|
model: ResponseToFileExtractorModel,
|
@@ -2472,14 +2544,10 @@ class ModelToComponentFactory:
|
|
2472
2544
|
schema_type_identifier = self._create_component_from_model(
|
2473
2545
|
model.schema_type_identifier, config=config, parameters=model.parameters or {}
|
2474
2546
|
)
|
2475
|
-
schema_filter = self._create_component_from_model(
|
2476
|
-
model.schema_filter, config=config, parameters=model.parameters or {}
|
2477
|
-
)
|
2478
2547
|
return DynamicSchemaLoader(
|
2479
2548
|
retriever=retriever,
|
2480
2549
|
config=config,
|
2481
2550
|
schema_transformations=schema_transformations,
|
2482
|
-
schema_filter=schema_filter,
|
2483
2551
|
schema_type_identifier=schema_type_identifier,
|
2484
2552
|
parameters=model.parameters or {},
|
2485
2553
|
)
|
@@ -3539,13 +3607,49 @@ class ModelToComponentFactory:
|
|
3539
3607
|
parameters=model.parameters or {},
|
3540
3608
|
)
|
3541
3609
|
|
3542
|
-
|
3543
|
-
|
3610
|
+
def create_spec(self, model: SpecModel, config: Config, **kwargs: Any) -> Spec:
|
3611
|
+
config_migrations = [
|
3612
|
+
self._create_component_from_model(migration, config)
|
3613
|
+
for migration in (
|
3614
|
+
model.config_normalization_rules.config_migrations
|
3615
|
+
if (
|
3616
|
+
model.config_normalization_rules
|
3617
|
+
and model.config_normalization_rules.config_migrations
|
3618
|
+
)
|
3619
|
+
else []
|
3620
|
+
)
|
3621
|
+
]
|
3622
|
+
config_transformations = [
|
3623
|
+
self._create_component_from_model(transformation, config)
|
3624
|
+
for transformation in (
|
3625
|
+
model.config_normalization_rules.transformations
|
3626
|
+
if (
|
3627
|
+
model.config_normalization_rules
|
3628
|
+
and model.config_normalization_rules.transformations
|
3629
|
+
)
|
3630
|
+
else []
|
3631
|
+
)
|
3632
|
+
]
|
3633
|
+
config_validations = [
|
3634
|
+
self._create_component_from_model(validation, config)
|
3635
|
+
for validation in (
|
3636
|
+
model.config_normalization_rules.validations
|
3637
|
+
if (
|
3638
|
+
model.config_normalization_rules
|
3639
|
+
and model.config_normalization_rules.validations
|
3640
|
+
)
|
3641
|
+
else []
|
3642
|
+
)
|
3643
|
+
]
|
3644
|
+
|
3544
3645
|
return Spec(
|
3545
3646
|
connection_specification=model.connection_specification,
|
3546
3647
|
documentation_url=model.documentation_url,
|
3547
3648
|
advanced_auth=model.advanced_auth,
|
3548
3649
|
parameters={},
|
3650
|
+
config_migrations=config_migrations,
|
3651
|
+
config_transformations=config_transformations,
|
3652
|
+
config_validations=config_validations,
|
3549
3653
|
)
|
3550
3654
|
|
3551
3655
|
def create_substream_partition_router(
|
@@ -3641,7 +3745,6 @@ class ModelToComponentFactory:
|
|
3641
3745
|
field_path=field_path, # type: ignore[arg-type] # field_path can be str and InterpolatedString
|
3642
3746
|
value=interpolated_value,
|
3643
3747
|
value_type=ModelToComponentFactory._json_schema_type_name_to_type(model.value_type),
|
3644
|
-
create_or_update=model.create_or_update,
|
3645
3748
|
parameters=model.parameters or {},
|
3646
3749
|
)
|
3647
3750
|
|
@@ -3688,24 +3791,16 @@ class ModelToComponentFactory:
|
|
3688
3791
|
|
3689
3792
|
return StreamConfig(
|
3690
3793
|
configs_pointer=model_configs_pointer,
|
3691
|
-
default_values=model.default_values,
|
3692
3794
|
parameters=model.parameters or {},
|
3693
3795
|
)
|
3694
3796
|
|
3695
3797
|
def create_config_components_resolver(
|
3696
3798
|
self, model: ConfigComponentsResolverModel, config: Config
|
3697
3799
|
) -> Any:
|
3698
|
-
|
3699
|
-
model.stream_config
|
3800
|
+
stream_config = self._create_component_from_model(
|
3801
|
+
model.stream_config, config=config, parameters=model.parameters or {}
|
3700
3802
|
)
|
3701
3803
|
|
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
|
-
|
3709
3804
|
components_mapping = [
|
3710
3805
|
self._create_component_from_model(
|
3711
3806
|
model=components_mapping_definition_model,
|
@@ -3718,7 +3813,7 @@ class ModelToComponentFactory:
|
|
3718
3813
|
]
|
3719
3814
|
|
3720
3815
|
return ConfigComponentsResolver(
|
3721
|
-
|
3816
|
+
stream_config=stream_config,
|
3722
3817
|
config=config,
|
3723
3818
|
components_mapping=components_mapping,
|
3724
3819
|
parameters=model.parameters or {},
|
@@ -22,7 +22,6 @@ 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
|
26
25
|
|
27
26
|
|
28
27
|
@dataclass(frozen=True)
|
@@ -35,7 +34,6 @@ class ResolvedComponentMappingDefinition:
|
|
35
34
|
value: "InterpolatedString"
|
36
35
|
value_type: Optional[Type[Any]]
|
37
36
|
parameters: InitVar[Mapping[str, Any]]
|
38
|
-
create_or_update: Optional[bool] = False
|
39
37
|
|
40
38
|
|
41
39
|
@deprecated("This class is experimental. Use at your own risk.", category=ExperimentalClassWarning)
|
@@ -4,8 +4,7 @@
|
|
4
4
|
|
5
5
|
from copy import deepcopy
|
6
6
|
from dataclasses import InitVar, dataclass, field
|
7
|
-
from
|
8
|
-
from typing import Any, Dict, Iterable, List, Mapping, Optional, Union
|
7
|
+
from typing import Any, Dict, Iterable, List, Mapping, Union
|
9
8
|
|
10
9
|
import dpath
|
11
10
|
from typing_extensions import deprecated
|
@@ -29,7 +28,6 @@ class StreamConfig:
|
|
29
28
|
|
30
29
|
configs_pointer: List[Union[InterpolatedString, str]]
|
31
30
|
parameters: InitVar[Mapping[str, Any]]
|
32
|
-
default_values: Optional[List[Any]] = None
|
33
31
|
|
34
32
|
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
35
33
|
self.configs_pointer = [
|
@@ -50,7 +48,7 @@ class ConfigComponentsResolver(ComponentsResolver):
|
|
50
48
|
parameters (InitVar[Mapping[str, Any]]): Additional parameters for interpolation.
|
51
49
|
"""
|
52
50
|
|
53
|
-
|
51
|
+
stream_config: StreamConfig
|
54
52
|
config: Config
|
55
53
|
components_mapping: List[ComponentMappingDefinition]
|
56
54
|
parameters: InitVar[Mapping[str, Any]]
|
@@ -84,7 +82,6 @@ class ConfigComponentsResolver(ComponentsResolver):
|
|
84
82
|
field_path=field_path,
|
85
83
|
value=interpolated_value,
|
86
84
|
value_type=component_mapping.value_type,
|
87
|
-
create_or_update=component_mapping.create_or_update,
|
88
85
|
parameters=parameters,
|
89
86
|
)
|
90
87
|
)
|
@@ -94,35 +91,17 @@ class ConfigComponentsResolver(ComponentsResolver):
|
|
94
91
|
)
|
95
92
|
|
96
93
|
@property
|
97
|
-
def _stream_config(self):
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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)]
|
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
|
126
105
|
|
127
106
|
def resolve_components(
|
128
107
|
self, stream_template_config: Dict[str, Any]
|
@@ -151,21 +130,7 @@ class ConfigComponentsResolver(ComponentsResolver):
|
|
151
130
|
)
|
152
131
|
|
153
132
|
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)
|
156
133
|
|
157
|
-
|
158
|
-
dpath.new(updated_config, path, parsed_value)
|
134
|
+
dpath.set(updated_config, path, value)
|
159
135
|
|
160
136
|
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,7 +10,6 @@ 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
|
14
13
|
from airbyte_cdk.sources.declarative.interpolation.interpolated_boolean import InterpolatedBoolean
|
15
14
|
from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
|
16
15
|
from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever
|
@@ -127,7 +126,6 @@ class DynamicSchemaLoader(SchemaLoader):
|
|
127
126
|
parameters: InitVar[Mapping[str, Any]]
|
128
127
|
schema_type_identifier: SchemaTypeIdentifier
|
129
128
|
schema_transformations: List[RecordTransformation] = field(default_factory=lambda: [])
|
130
|
-
schema_filter: Optional[RecordFilter] = None
|
131
129
|
|
132
130
|
def get_json_schema(self) -> Mapping[str, Any]:
|
133
131
|
"""
|
@@ -153,18 +151,20 @@ class DynamicSchemaLoader(SchemaLoader):
|
|
153
151
|
)
|
154
152
|
properties[key] = value
|
155
153
|
|
156
|
-
|
154
|
+
transformed_properties = self._transform(properties, {})
|
157
155
|
|
158
156
|
return {
|
159
157
|
"$schema": "https://json-schema.org/draft-07/schema#",
|
160
158
|
"type": "object",
|
161
159
|
"additionalProperties": True,
|
162
|
-
"properties":
|
160
|
+
"properties": transformed_properties,
|
163
161
|
}
|
164
162
|
|
165
163
|
def _transform(
|
166
164
|
self,
|
167
165
|
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,21 +173,6 @@ 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
|
-
|
191
176
|
def _get_key(
|
192
177
|
self,
|
193
178
|
raw_schema: MutableMapping[str, Any],
|
@@ -2,15 +2,33 @@
|
|
2
2
|
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
3
|
#
|
4
4
|
|
5
|
-
|
6
|
-
from
|
5
|
+
import json
|
6
|
+
from dataclasses import InitVar, dataclass, field
|
7
|
+
from typing import Any, List, Mapping, MutableMapping, Optional
|
7
8
|
|
9
|
+
import orjson
|
10
|
+
|
11
|
+
from airbyte_cdk.config_observation import create_connector_config_control_message
|
12
|
+
from airbyte_cdk.entrypoint import AirbyteEntrypoint
|
8
13
|
from airbyte_cdk.models import (
|
9
14
|
AdvancedAuth,
|
10
15
|
ConnectorSpecification,
|
11
16
|
ConnectorSpecificationSerializer,
|
12
17
|
)
|
18
|
+
from airbyte_cdk.models.airbyte_protocol_serializers import AirbyteMessageSerializer
|
13
19
|
from airbyte_cdk.sources.declarative.models.declarative_component_schema import AuthFlow
|
20
|
+
from airbyte_cdk.sources.declarative.transformations.config_transformations.config_transformation import (
|
21
|
+
ConfigTransformation,
|
22
|
+
)
|
23
|
+
from airbyte_cdk.sources.declarative.validators.validator import Validator
|
24
|
+
from airbyte_cdk.sources.message.repository import InMemoryMessageRepository, MessageRepository
|
25
|
+
from airbyte_cdk.sources.source import Source
|
26
|
+
|
27
|
+
|
28
|
+
@dataclass
|
29
|
+
class ConfigMigration:
|
30
|
+
transformations: List[ConfigTransformation]
|
31
|
+
description: Optional[str] = None
|
14
32
|
|
15
33
|
|
16
34
|
@dataclass
|
@@ -27,6 +45,10 @@ class Spec:
|
|
27
45
|
parameters: InitVar[Mapping[str, Any]]
|
28
46
|
documentation_url: Optional[str] = None
|
29
47
|
advanced_auth: Optional[AuthFlow] = None
|
48
|
+
config_migrations: List[ConfigMigration] = field(default_factory=list)
|
49
|
+
config_transformations: List[ConfigTransformation] = field(default_factory=list)
|
50
|
+
config_validations: List[Validator] = field(default_factory=list)
|
51
|
+
message_repository: MessageRepository = InMemoryMessageRepository()
|
30
52
|
|
31
53
|
def generate_spec(self) -> ConnectorSpecification:
|
32
54
|
"""
|
@@ -46,3 +68,50 @@ class Spec:
|
|
46
68
|
|
47
69
|
# We remap these keys to camel case because that's the existing format expected by the rest of the platform
|
48
70
|
return ConnectorSpecificationSerializer.load(obj)
|
71
|
+
|
72
|
+
def migrate_config(
|
73
|
+
self, args: List[str], source: Source, config: MutableMapping[str, Any]
|
74
|
+
) -> None:
|
75
|
+
"""
|
76
|
+
Apply all specified config transformations to the provided config and save the modified config to the given path and emit a control message.
|
77
|
+
|
78
|
+
:param args: Command line arguments
|
79
|
+
:param source: Source instance
|
80
|
+
:param config: The user-provided config to migrate
|
81
|
+
"""
|
82
|
+
config_path = AirbyteEntrypoint(source).extract_config(args)
|
83
|
+
|
84
|
+
if not config_path:
|
85
|
+
return
|
86
|
+
|
87
|
+
mutable_config = dict(config)
|
88
|
+
for migration in self.config_migrations:
|
89
|
+
for transformation in migration.transformations:
|
90
|
+
transformation.transform(mutable_config)
|
91
|
+
|
92
|
+
if mutable_config != config:
|
93
|
+
with open(config_path, "w") as f:
|
94
|
+
json.dump(mutable_config, f)
|
95
|
+
self.message_repository.emit_message(
|
96
|
+
create_connector_config_control_message(mutable_config)
|
97
|
+
)
|
98
|
+
for message in self.message_repository.consume_queue():
|
99
|
+
print(orjson.dumps(AirbyteMessageSerializer.dump(message)).decode())
|
100
|
+
|
101
|
+
def transform_config(self, config: MutableMapping[str, Any]) -> None:
|
102
|
+
"""
|
103
|
+
Apply all config transformations to the provided config.
|
104
|
+
|
105
|
+
:param config: The user-provided configuration
|
106
|
+
"""
|
107
|
+
for transformation in self.config_transformations:
|
108
|
+
transformation.transform(config)
|
109
|
+
|
110
|
+
def validate_config(self, config: MutableMapping[str, Any]) -> None:
|
111
|
+
"""
|
112
|
+
Apply all config validations to the provided config.
|
113
|
+
|
114
|
+
:param config: The user-provided configuration
|
115
|
+
"""
|
116
|
+
for validator in self.config_validations:
|
117
|
+
validator.validate(config)
|