airbyte-cdk 0.0.0.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.
- airbyte_cdk/__init__.py +358 -0
- airbyte_cdk/cli/__init__.py +1 -0
- airbyte_cdk/cli/source_declarative_manifest/__init__.py +5 -0
- airbyte_cdk/cli/source_declarative_manifest/_run.py +236 -0
- airbyte_cdk/cli/source_declarative_manifest/spec.json +17 -0
- airbyte_cdk/config_observation.py +104 -0
- airbyte_cdk/connector.py +123 -0
- airbyte_cdk/connector_builder/README.md +53 -0
- airbyte_cdk/connector_builder/__init__.py +3 -0
- airbyte_cdk/connector_builder/connector_builder_handler.py +121 -0
- airbyte_cdk/connector_builder/main.py +107 -0
- airbyte_cdk/connector_builder/models.py +73 -0
- airbyte_cdk/connector_builder/test_reader/__init__.py +7 -0
- airbyte_cdk/connector_builder/test_reader/helpers.py +689 -0
- airbyte_cdk/connector_builder/test_reader/message_grouper.py +173 -0
- airbyte_cdk/connector_builder/test_reader/reader.py +441 -0
- airbyte_cdk/connector_builder/test_reader/types.py +83 -0
- airbyte_cdk/destinations/__init__.py +8 -0
- airbyte_cdk/destinations/destination.py +154 -0
- airbyte_cdk/destinations/vector_db_based/README.md +37 -0
- airbyte_cdk/destinations/vector_db_based/__init__.py +38 -0
- airbyte_cdk/destinations/vector_db_based/config.py +298 -0
- airbyte_cdk/destinations/vector_db_based/document_processor.py +223 -0
- airbyte_cdk/destinations/vector_db_based/embedder.py +303 -0
- airbyte_cdk/destinations/vector_db_based/indexer.py +78 -0
- airbyte_cdk/destinations/vector_db_based/test_utils.py +63 -0
- airbyte_cdk/destinations/vector_db_based/utils.py +35 -0
- airbyte_cdk/destinations/vector_db_based/writer.py +104 -0
- airbyte_cdk/entrypoint.py +414 -0
- airbyte_cdk/exception_handler.py +56 -0
- airbyte_cdk/logger.py +109 -0
- airbyte_cdk/models/__init__.py +72 -0
- airbyte_cdk/models/airbyte_protocol.py +88 -0
- airbyte_cdk/models/airbyte_protocol_serializers.py +44 -0
- airbyte_cdk/models/well_known_types.py +5 -0
- airbyte_cdk/py.typed +0 -0
- airbyte_cdk/sources/__init__.py +26 -0
- airbyte_cdk/sources/abstract_source.py +326 -0
- airbyte_cdk/sources/concurrent_source/__init__.py +8 -0
- airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py +255 -0
- airbyte_cdk/sources/concurrent_source/concurrent_source.py +165 -0
- airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py +147 -0
- airbyte_cdk/sources/concurrent_source/partition_generation_completed_sentinel.py +24 -0
- airbyte_cdk/sources/concurrent_source/stream_thread_exception.py +25 -0
- airbyte_cdk/sources/concurrent_source/thread_pool_manager.py +115 -0
- airbyte_cdk/sources/config.py +27 -0
- airbyte_cdk/sources/connector_state_manager.py +161 -0
- airbyte_cdk/sources/declarative/__init__.py +3 -0
- airbyte_cdk/sources/declarative/async_job/__init__.py +0 -0
- airbyte_cdk/sources/declarative/async_job/job.py +52 -0
- airbyte_cdk/sources/declarative/async_job/job_orchestrator.py +525 -0
- airbyte_cdk/sources/declarative/async_job/job_tracker.py +79 -0
- airbyte_cdk/sources/declarative/async_job/repository.py +35 -0
- airbyte_cdk/sources/declarative/async_job/status.py +24 -0
- airbyte_cdk/sources/declarative/async_job/timer.py +39 -0
- airbyte_cdk/sources/declarative/auth/__init__.py +8 -0
- airbyte_cdk/sources/declarative/auth/declarative_authenticator.py +42 -0
- airbyte_cdk/sources/declarative/auth/jwt.py +197 -0
- airbyte_cdk/sources/declarative/auth/oauth.py +293 -0
- airbyte_cdk/sources/declarative/auth/selective_authenticator.py +45 -0
- airbyte_cdk/sources/declarative/auth/token.py +267 -0
- airbyte_cdk/sources/declarative/auth/token_provider.py +82 -0
- airbyte_cdk/sources/declarative/checks/__init__.py +24 -0
- airbyte_cdk/sources/declarative/checks/check_dynamic_stream.py +61 -0
- airbyte_cdk/sources/declarative/checks/check_stream.py +56 -0
- airbyte_cdk/sources/declarative/checks/connection_checker.py +35 -0
- airbyte_cdk/sources/declarative/concurrency_level/__init__.py +7 -0
- airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py +50 -0
- airbyte_cdk/sources/declarative/concurrent_declarative_source.py +526 -0
- airbyte_cdk/sources/declarative/datetime/__init__.py +3 -0
- airbyte_cdk/sources/declarative/datetime/datetime_parser.py +65 -0
- airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +118 -0
- airbyte_cdk/sources/declarative/declarative_component_schema.yaml +3975 -0
- airbyte_cdk/sources/declarative/declarative_source.py +36 -0
- airbyte_cdk/sources/declarative/declarative_stream.py +241 -0
- airbyte_cdk/sources/declarative/decoders/__init__.py +33 -0
- airbyte_cdk/sources/declarative/decoders/composite_raw_decoder.py +218 -0
- airbyte_cdk/sources/declarative/decoders/decoder.py +32 -0
- airbyte_cdk/sources/declarative/decoders/decoder_parser.py +30 -0
- airbyte_cdk/sources/declarative/decoders/json_decoder.py +65 -0
- airbyte_cdk/sources/declarative/decoders/noop_decoder.py +21 -0
- airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py +39 -0
- airbyte_cdk/sources/declarative/decoders/xml_decoder.py +98 -0
- airbyte_cdk/sources/declarative/decoders/zipfile_decoder.py +56 -0
- airbyte_cdk/sources/declarative/exceptions.py +9 -0
- airbyte_cdk/sources/declarative/extractors/__init__.py +21 -0
- airbyte_cdk/sources/declarative/extractors/dpath_extractor.py +86 -0
- airbyte_cdk/sources/declarative/extractors/http_selector.py +37 -0
- airbyte_cdk/sources/declarative/extractors/record_extractor.py +27 -0
- airbyte_cdk/sources/declarative/extractors/record_filter.py +91 -0
- airbyte_cdk/sources/declarative/extractors/record_selector.py +170 -0
- airbyte_cdk/sources/declarative/extractors/response_to_file_extractor.py +176 -0
- airbyte_cdk/sources/declarative/extractors/type_transformer.py +55 -0
- airbyte_cdk/sources/declarative/incremental/__init__.py +37 -0
- airbyte_cdk/sources/declarative/incremental/concurrent_partition_cursor.py +497 -0
- airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +459 -0
- airbyte_cdk/sources/declarative/incremental/declarative_cursor.py +13 -0
- airbyte_cdk/sources/declarative/incremental/global_substream_cursor.py +357 -0
- airbyte_cdk/sources/declarative/incremental/per_partition_cursor.py +380 -0
- airbyte_cdk/sources/declarative/incremental/per_partition_with_global.py +200 -0
- airbyte_cdk/sources/declarative/incremental/resumable_full_refresh_cursor.py +122 -0
- airbyte_cdk/sources/declarative/interpolation/__init__.py +9 -0
- airbyte_cdk/sources/declarative/interpolation/filters.py +139 -0
- airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py +66 -0
- airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py +56 -0
- airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py +52 -0
- airbyte_cdk/sources/declarative/interpolation/interpolated_string.py +79 -0
- airbyte_cdk/sources/declarative/interpolation/interpolation.py +34 -0
- airbyte_cdk/sources/declarative/interpolation/jinja.py +161 -0
- airbyte_cdk/sources/declarative/interpolation/macros.py +191 -0
- airbyte_cdk/sources/declarative/manifest_declarative_source.py +421 -0
- airbyte_cdk/sources/declarative/migrations/__init__.py +0 -0
- airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py +98 -0
- airbyte_cdk/sources/declarative/migrations/state_migration.py +24 -0
- airbyte_cdk/sources/declarative/models/__init__.py +2 -0
- airbyte_cdk/sources/declarative/models/declarative_component_schema.py +2503 -0
- airbyte_cdk/sources/declarative/parsers/__init__.py +3 -0
- airbyte_cdk/sources/declarative/parsers/custom_code_compiler.py +157 -0
- airbyte_cdk/sources/declarative/parsers/custom_exceptions.py +21 -0
- airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +172 -0
- airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py +213 -0
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +3407 -0
- airbyte_cdk/sources/declarative/partition_routers/__init__.py +29 -0
- airbyte_cdk/sources/declarative/partition_routers/async_job_partition_router.py +65 -0
- airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py +176 -0
- airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py +121 -0
- airbyte_cdk/sources/declarative/partition_routers/partition_router.py +62 -0
- airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py +63 -0
- airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py +437 -0
- airbyte_cdk/sources/declarative/requesters/README.md +56 -0
- airbyte_cdk/sources/declarative/requesters/__init__.py +9 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py +25 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +23 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py +45 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py +45 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py +41 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py +70 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py +77 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py +17 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py +101 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py +147 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_filter.py +40 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py +17 -0
- airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py +179 -0
- airbyte_cdk/sources/declarative/requesters/http_job_repository.py +350 -0
- airbyte_cdk/sources/declarative/requesters/http_requester.py +433 -0
- airbyte_cdk/sources/declarative/requesters/paginators/__init__.py +21 -0
- airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +327 -0
- airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py +76 -0
- airbyte_cdk/sources/declarative/requesters/paginators/paginator.py +65 -0
- airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py +25 -0
- airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py +98 -0
- airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py +102 -0
- airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py +71 -0
- airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py +48 -0
- airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py +66 -0
- airbyte_cdk/sources/declarative/requesters/request_option.py +117 -0
- airbyte_cdk/sources/declarative/requesters/request_options/__init__.py +23 -0
- airbyte_cdk/sources/declarative/requesters/request_options/datetime_based_request_options_provider.py +92 -0
- airbyte_cdk/sources/declarative/requesters/request_options/default_request_options_provider.py +60 -0
- airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py +59 -0
- airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py +68 -0
- airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py +119 -0
- airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +79 -0
- airbyte_cdk/sources/declarative/requesters/request_path.py +15 -0
- airbyte_cdk/sources/declarative/requesters/requester.py +144 -0
- airbyte_cdk/sources/declarative/resolvers/__init__.py +41 -0
- airbyte_cdk/sources/declarative/resolvers/components_resolver.py +55 -0
- airbyte_cdk/sources/declarative/resolvers/config_components_resolver.py +136 -0
- airbyte_cdk/sources/declarative/resolvers/http_components_resolver.py +112 -0
- airbyte_cdk/sources/declarative/retrievers/__init__.py +19 -0
- airbyte_cdk/sources/declarative/retrievers/async_retriever.py +124 -0
- airbyte_cdk/sources/declarative/retrievers/file_uploader.py +89 -0
- airbyte_cdk/sources/declarative/retrievers/retriever.py +54 -0
- airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +702 -0
- airbyte_cdk/sources/declarative/schema/__init__.py +25 -0
- airbyte_cdk/sources/declarative/schema/default_schema_loader.py +47 -0
- airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py +285 -0
- airbyte_cdk/sources/declarative/schema/inline_schema_loader.py +19 -0
- airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py +92 -0
- airbyte_cdk/sources/declarative/schema/schema_loader.py +17 -0
- airbyte_cdk/sources/declarative/spec/__init__.py +7 -0
- airbyte_cdk/sources/declarative/spec/spec.py +48 -0
- airbyte_cdk/sources/declarative/stream_slicers/__init__.py +7 -0
- airbyte_cdk/sources/declarative/stream_slicers/declarative_partition_generator.py +93 -0
- airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py +25 -0
- airbyte_cdk/sources/declarative/transformations/__init__.py +17 -0
- airbyte_cdk/sources/declarative/transformations/add_fields.py +146 -0
- airbyte_cdk/sources/declarative/transformations/dpath_flatten_fields.py +61 -0
- airbyte_cdk/sources/declarative/transformations/flatten_fields.py +52 -0
- airbyte_cdk/sources/declarative/transformations/keys_replace_transformation.py +61 -0
- airbyte_cdk/sources/declarative/transformations/keys_to_lower_transformation.py +22 -0
- airbyte_cdk/sources/declarative/transformations/keys_to_snake_transformation.py +68 -0
- airbyte_cdk/sources/declarative/transformations/remove_fields.py +75 -0
- airbyte_cdk/sources/declarative/transformations/transformation.py +37 -0
- airbyte_cdk/sources/declarative/types.py +25 -0
- airbyte_cdk/sources/declarative/yaml_declarative_source.py +67 -0
- airbyte_cdk/sources/file_based/README.md +152 -0
- airbyte_cdk/sources/file_based/__init__.py +24 -0
- airbyte_cdk/sources/file_based/availability_strategy/__init__.py +11 -0
- airbyte_cdk/sources/file_based/availability_strategy/abstract_file_based_availability_strategy.py +73 -0
- airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availability_strategy.py +149 -0
- airbyte_cdk/sources/file_based/config/__init__.py +0 -0
- airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py +153 -0
- airbyte_cdk/sources/file_based/config/avro_format.py +25 -0
- airbyte_cdk/sources/file_based/config/csv_format.py +210 -0
- airbyte_cdk/sources/file_based/config/excel_format.py +18 -0
- airbyte_cdk/sources/file_based/config/file_based_stream_config.py +99 -0
- airbyte_cdk/sources/file_based/config/jsonl_format.py +18 -0
- airbyte_cdk/sources/file_based/config/parquet_format.py +25 -0
- airbyte_cdk/sources/file_based/config/unstructured_format.py +102 -0
- airbyte_cdk/sources/file_based/config/validate_config_transfer_modes.py +81 -0
- airbyte_cdk/sources/file_based/discovery_policy/__init__.py +8 -0
- airbyte_cdk/sources/file_based/discovery_policy/abstract_discovery_policy.py +21 -0
- airbyte_cdk/sources/file_based/discovery_policy/default_discovery_policy.py +33 -0
- airbyte_cdk/sources/file_based/exceptions.py +159 -0
- airbyte_cdk/sources/file_based/file_based_source.py +466 -0
- airbyte_cdk/sources/file_based/file_based_stream_permissions_reader.py +123 -0
- airbyte_cdk/sources/file_based/file_based_stream_reader.py +209 -0
- airbyte_cdk/sources/file_based/file_record_data.py +22 -0
- airbyte_cdk/sources/file_based/file_types/__init__.py +37 -0
- airbyte_cdk/sources/file_based/file_types/avro_parser.py +233 -0
- airbyte_cdk/sources/file_based/file_types/csv_parser.py +527 -0
- airbyte_cdk/sources/file_based/file_types/excel_parser.py +196 -0
- airbyte_cdk/sources/file_based/file_types/file_transfer.py +30 -0
- airbyte_cdk/sources/file_based/file_types/file_type_parser.py +86 -0
- airbyte_cdk/sources/file_based/file_types/jsonl_parser.py +145 -0
- airbyte_cdk/sources/file_based/file_types/parquet_parser.py +275 -0
- airbyte_cdk/sources/file_based/file_types/unstructured_parser.py +480 -0
- airbyte_cdk/sources/file_based/remote_file.py +18 -0
- airbyte_cdk/sources/file_based/schema_helpers.py +281 -0
- airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py +17 -0
- airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py +20 -0
- airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py +52 -0
- airbyte_cdk/sources/file_based/stream/__init__.py +13 -0
- airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py +197 -0
- airbyte_cdk/sources/file_based/stream/concurrent/__init__.py +0 -0
- airbyte_cdk/sources/file_based/stream/concurrent/adapters.py +343 -0
- airbyte_cdk/sources/file_based/stream/concurrent/cursor/__init__.py +9 -0
- airbyte_cdk/sources/file_based/stream/concurrent/cursor/abstract_concurrent_file_based_cursor.py +59 -0
- airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py +313 -0
- airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_final_state_cursor.py +83 -0
- airbyte_cdk/sources/file_based/stream/cursor/__init__.py +4 -0
- airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py +66 -0
- airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py +149 -0
- airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +396 -0
- airbyte_cdk/sources/file_based/stream/identities_stream.py +49 -0
- airbyte_cdk/sources/file_based/stream/permissions_file_based_stream.py +92 -0
- airbyte_cdk/sources/file_based/types.py +10 -0
- airbyte_cdk/sources/http_config.py +10 -0
- airbyte_cdk/sources/http_logger.py +55 -0
- airbyte_cdk/sources/message/__init__.py +19 -0
- airbyte_cdk/sources/message/repository.py +137 -0
- airbyte_cdk/sources/source.py +95 -0
- airbyte_cdk/sources/specs/transfer_modes.py +26 -0
- airbyte_cdk/sources/streams/__init__.py +8 -0
- airbyte_cdk/sources/streams/availability_strategy.py +84 -0
- airbyte_cdk/sources/streams/call_rate.py +704 -0
- airbyte_cdk/sources/streams/checkpoint/__init__.py +26 -0
- airbyte_cdk/sources/streams/checkpoint/checkpoint_reader.py +335 -0
- airbyte_cdk/sources/streams/checkpoint/cursor.py +77 -0
- airbyte_cdk/sources/streams/checkpoint/per_partition_key_serializer.py +22 -0
- airbyte_cdk/sources/streams/checkpoint/resumable_full_refresh_cursor.py +51 -0
- airbyte_cdk/sources/streams/checkpoint/substream_resumable_full_refresh_cursor.py +110 -0
- airbyte_cdk/sources/streams/concurrent/README.md +7 -0
- airbyte_cdk/sources/streams/concurrent/__init__.py +3 -0
- airbyte_cdk/sources/streams/concurrent/abstract_stream.py +96 -0
- airbyte_cdk/sources/streams/concurrent/abstract_stream_facade.py +37 -0
- airbyte_cdk/sources/streams/concurrent/adapters.py +397 -0
- airbyte_cdk/sources/streams/concurrent/availability_strategy.py +94 -0
- airbyte_cdk/sources/streams/concurrent/clamping.py +99 -0
- airbyte_cdk/sources/streams/concurrent/cursor.py +481 -0
- airbyte_cdk/sources/streams/concurrent/cursor_types.py +32 -0
- airbyte_cdk/sources/streams/concurrent/default_stream.py +102 -0
- airbyte_cdk/sources/streams/concurrent/exceptions.py +18 -0
- airbyte_cdk/sources/streams/concurrent/helpers.py +42 -0
- airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py +64 -0
- airbyte_cdk/sources/streams/concurrent/partition_reader.py +45 -0
- airbyte_cdk/sources/streams/concurrent/partitions/__init__.py +3 -0
- airbyte_cdk/sources/streams/concurrent/partitions/partition.py +48 -0
- airbyte_cdk/sources/streams/concurrent/partitions/partition_generator.py +18 -0
- airbyte_cdk/sources/streams/concurrent/partitions/stream_slicer.py +21 -0
- airbyte_cdk/sources/streams/concurrent/partitions/types.py +38 -0
- airbyte_cdk/sources/streams/concurrent/state_converters/__init__.py +0 -0
- airbyte_cdk/sources/streams/concurrent/state_converters/abstract_stream_state_converter.py +182 -0
- airbyte_cdk/sources/streams/concurrent/state_converters/datetime_stream_state_converter.py +223 -0
- airbyte_cdk/sources/streams/concurrent/state_converters/incrementing_count_stream_state_converter.py +92 -0
- airbyte_cdk/sources/streams/core.py +703 -0
- airbyte_cdk/sources/streams/http/__init__.py +10 -0
- airbyte_cdk/sources/streams/http/availability_strategy.py +54 -0
- airbyte_cdk/sources/streams/http/error_handlers/__init__.py +22 -0
- airbyte_cdk/sources/streams/http/error_handlers/backoff_strategy.py +28 -0
- airbyte_cdk/sources/streams/http/error_handlers/default_backoff_strategy.py +17 -0
- airbyte_cdk/sources/streams/http/error_handlers/default_error_mapping.py +86 -0
- airbyte_cdk/sources/streams/http/error_handlers/error_handler.py +42 -0
- airbyte_cdk/sources/streams/http/error_handlers/error_message_parser.py +19 -0
- airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py +110 -0
- airbyte_cdk/sources/streams/http/error_handlers/json_error_message_parser.py +52 -0
- airbyte_cdk/sources/streams/http/error_handlers/response_models.py +65 -0
- airbyte_cdk/sources/streams/http/exceptions.py +61 -0
- airbyte_cdk/sources/streams/http/http.py +673 -0
- airbyte_cdk/sources/streams/http/http_client.py +531 -0
- airbyte_cdk/sources/streams/http/rate_limiting.py +158 -0
- airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py +14 -0
- airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +479 -0
- airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py +34 -0
- airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +436 -0
- airbyte_cdk/sources/streams/http/requests_native_auth/token.py +83 -0
- airbyte_cdk/sources/streams/permissions/identities_stream.py +75 -0
- airbyte_cdk/sources/streams/utils/__init__.py +3 -0
- airbyte_cdk/sources/types.py +169 -0
- airbyte_cdk/sources/utils/__init__.py +7 -0
- airbyte_cdk/sources/utils/casing.py +12 -0
- airbyte_cdk/sources/utils/files_directory.py +15 -0
- airbyte_cdk/sources/utils/record_helper.py +53 -0
- airbyte_cdk/sources/utils/schema_helpers.py +230 -0
- airbyte_cdk/sources/utils/slice_logger.py +57 -0
- airbyte_cdk/sources/utils/transform.py +277 -0
- airbyte_cdk/sources/utils/types.py +7 -0
- airbyte_cdk/sql/__init__.py +0 -0
- airbyte_cdk/sql/_util/__init__.py +0 -0
- airbyte_cdk/sql/_util/hashing.py +34 -0
- airbyte_cdk/sql/_util/name_normalizers.py +92 -0
- airbyte_cdk/sql/constants.py +32 -0
- airbyte_cdk/sql/exceptions.py +235 -0
- airbyte_cdk/sql/secrets.py +123 -0
- airbyte_cdk/sql/shared/__init__.py +15 -0
- airbyte_cdk/sql/shared/catalog_providers.py +145 -0
- airbyte_cdk/sql/shared/sql_processor.py +786 -0
- airbyte_cdk/sql/types.py +160 -0
- airbyte_cdk/test/__init__.py +7 -0
- airbyte_cdk/test/catalog_builder.py +81 -0
- airbyte_cdk/test/entrypoint_wrapper.py +250 -0
- airbyte_cdk/test/mock_http/__init__.py +6 -0
- airbyte_cdk/test/mock_http/matcher.py +41 -0
- airbyte_cdk/test/mock_http/mocker.py +185 -0
- airbyte_cdk/test/mock_http/request.py +103 -0
- airbyte_cdk/test/mock_http/response.py +28 -0
- airbyte_cdk/test/mock_http/response_builder.py +237 -0
- airbyte_cdk/test/state_builder.py +33 -0
- airbyte_cdk/test/utils/__init__.py +1 -0
- airbyte_cdk/test/utils/data.py +24 -0
- airbyte_cdk/test/utils/http_mocking.py +16 -0
- airbyte_cdk/test/utils/manifest_only_fixtures.py +59 -0
- airbyte_cdk/test/utils/reading.py +26 -0
- airbyte_cdk/utils/__init__.py +10 -0
- airbyte_cdk/utils/airbyte_secrets_utils.py +80 -0
- airbyte_cdk/utils/analytics_message.py +25 -0
- airbyte_cdk/utils/constants.py +5 -0
- airbyte_cdk/utils/datetime_format_inferrer.py +94 -0
- airbyte_cdk/utils/datetime_helpers.py +499 -0
- airbyte_cdk/utils/event_timing.py +85 -0
- airbyte_cdk/utils/is_cloud_environment.py +18 -0
- airbyte_cdk/utils/mapping_helpers.py +162 -0
- airbyte_cdk/utils/message_utils.py +26 -0
- airbyte_cdk/utils/oneof_option_config.py +33 -0
- airbyte_cdk/utils/print_buffer.py +75 -0
- airbyte_cdk/utils/schema_inferrer.py +270 -0
- airbyte_cdk/utils/slice_hasher.py +37 -0
- airbyte_cdk/utils/spec_schema_transformations.py +26 -0
- airbyte_cdk/utils/stream_status_utils.py +43 -0
- airbyte_cdk/utils/traced_exception.py +145 -0
- airbyte_cdk-0.0.0.dev0.dist-info/LICENSE.txt +19 -0
- airbyte_cdk-0.0.0.dev0.dist-info/LICENSE_SHORT +1 -0
- airbyte_cdk-0.0.0.dev0.dist-info/METADATA +111 -0
- airbyte_cdk-0.0.0.dev0.dist-info/RECORD +368 -0
- airbyte_cdk-0.0.0.dev0.dist-info/WHEEL +4 -0
- airbyte_cdk-0.0.0.dev0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from dataclasses import InitVar, dataclass
|
|
6
|
+
from typing import Any, Mapping, Optional, Union
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
from airbyte_cdk.sources.declarative.interpolation import InterpolatedString
|
|
11
|
+
from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
|
|
12
|
+
PaginationStrategy,
|
|
13
|
+
)
|
|
14
|
+
from airbyte_cdk.sources.types import Config, Record
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class PageIncrement(PaginationStrategy):
|
|
19
|
+
"""
|
|
20
|
+
Pagination strategy that returns the number of pages reads so far and returns it as the next page token
|
|
21
|
+
|
|
22
|
+
Attributes:
|
|
23
|
+
page_size (int): the number of records to request
|
|
24
|
+
start_from_page (int): number of the initial page
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
config: Config
|
|
28
|
+
page_size: Optional[Union[str, int]]
|
|
29
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
30
|
+
start_from_page: int = 0
|
|
31
|
+
inject_on_first_request: bool = False
|
|
32
|
+
|
|
33
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
34
|
+
if isinstance(self.page_size, int) or (self.page_size is None):
|
|
35
|
+
self._page_size = self.page_size
|
|
36
|
+
else:
|
|
37
|
+
page_size = InterpolatedString(self.page_size, parameters=parameters).eval(self.config)
|
|
38
|
+
if not isinstance(page_size, int):
|
|
39
|
+
raise Exception(f"{page_size} is of type {type(page_size)}. Expected {int}")
|
|
40
|
+
self._page_size = page_size
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def initial_token(self) -> Optional[Any]:
|
|
44
|
+
if self.inject_on_first_request:
|
|
45
|
+
return self.start_from_page
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
def next_page_token(
|
|
49
|
+
self,
|
|
50
|
+
response: requests.Response,
|
|
51
|
+
last_page_size: int,
|
|
52
|
+
last_record: Optional[Record],
|
|
53
|
+
last_page_token_value: Optional[Any],
|
|
54
|
+
) -> Optional[Any]:
|
|
55
|
+
# Stop paginating when there are fewer records than the page size or the current page has no records
|
|
56
|
+
if (self._page_size and last_page_size < self._page_size) or last_page_size == 0:
|
|
57
|
+
return None
|
|
58
|
+
elif last_page_token_value is None:
|
|
59
|
+
# If the PageIncrement strategy does not inject on the first request, the incoming last_page_token_value
|
|
60
|
+
# may be None. When this is the case, we assume we've already requested the first page specified by
|
|
61
|
+
# start_from_page and must now get the next page
|
|
62
|
+
return self.start_from_page + 1
|
|
63
|
+
elif not isinstance(last_page_token_value, int):
|
|
64
|
+
raise ValueError(
|
|
65
|
+
f"Last page token value {last_page_token_value} for PageIncrement pagination strategy was not an integer"
|
|
66
|
+
)
|
|
67
|
+
else:
|
|
68
|
+
return last_page_token_value + 1
|
|
69
|
+
|
|
70
|
+
def get_page_size(self) -> Optional[int]:
|
|
71
|
+
return self._page_size
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from abc import abstractmethod
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Any, Optional
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
|
|
11
|
+
from airbyte_cdk.sources.types import Record
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class PaginationStrategy:
|
|
16
|
+
"""
|
|
17
|
+
Defines how to get the next page token
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
@abstractmethod
|
|
22
|
+
def initial_token(self) -> Optional[Any]:
|
|
23
|
+
"""
|
|
24
|
+
Return the initial value of the token
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def next_page_token(
|
|
29
|
+
self,
|
|
30
|
+
response: requests.Response,
|
|
31
|
+
last_page_size: int,
|
|
32
|
+
last_record: Optional[Record],
|
|
33
|
+
last_page_token_value: Optional[Any],
|
|
34
|
+
) -> Optional[Any]:
|
|
35
|
+
"""
|
|
36
|
+
:param response: response to process
|
|
37
|
+
:param last_page_size: the number of records read from the response
|
|
38
|
+
:param last_record: the last record extracted from the response
|
|
39
|
+
:param last_page_token_value: The current value of the page token made on the last request
|
|
40
|
+
:return: next page token. Returns None if there are no more pages to fetch
|
|
41
|
+
"""
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
@abstractmethod
|
|
45
|
+
def get_page_size(self) -> Optional[int]:
|
|
46
|
+
"""
|
|
47
|
+
:return: page size: The number of records to fetch in a page. Returns None if unspecified
|
|
48
|
+
"""
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from typing import Any, Optional
|
|
7
|
+
|
|
8
|
+
import requests
|
|
9
|
+
|
|
10
|
+
from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor
|
|
11
|
+
from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
|
|
12
|
+
PaginationStrategy,
|
|
13
|
+
)
|
|
14
|
+
from airbyte_cdk.sources.streams.concurrent.cursor import ConcurrentCursor
|
|
15
|
+
from airbyte_cdk.sources.types import Record
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class PaginationStopCondition(ABC):
|
|
19
|
+
@abstractmethod
|
|
20
|
+
def is_met(self, record: Record) -> bool:
|
|
21
|
+
"""
|
|
22
|
+
Given a condition is met, the pagination will stop
|
|
23
|
+
|
|
24
|
+
:param record: a record used to evaluate the condition
|
|
25
|
+
"""
|
|
26
|
+
raise NotImplementedError()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class CursorStopCondition(PaginationStopCondition):
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
cursor: DeclarativeCursor
|
|
33
|
+
| ConcurrentCursor, # migrate to use both old and concurrent versions
|
|
34
|
+
):
|
|
35
|
+
self._cursor = cursor
|
|
36
|
+
|
|
37
|
+
def is_met(self, record: Record) -> bool:
|
|
38
|
+
return not self._cursor.should_be_synced(record)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class StopConditionPaginationStrategyDecorator(PaginationStrategy):
|
|
42
|
+
def __init__(self, _delegate: PaginationStrategy, stop_condition: PaginationStopCondition):
|
|
43
|
+
self._delegate = _delegate
|
|
44
|
+
self._stop_condition = stop_condition
|
|
45
|
+
|
|
46
|
+
def next_page_token(
|
|
47
|
+
self,
|
|
48
|
+
response: requests.Response,
|
|
49
|
+
last_page_size: int,
|
|
50
|
+
last_record: Optional[Record],
|
|
51
|
+
last_page_token_value: Optional[Any] = None,
|
|
52
|
+
) -> Optional[Any]:
|
|
53
|
+
# We evaluate in reverse order because the assumption is that most of the APIs using data feed structure
|
|
54
|
+
# will return records in descending order. In terms of performance/memory, we return the records lazily
|
|
55
|
+
if last_record and self._stop_condition.is_met(last_record):
|
|
56
|
+
return None
|
|
57
|
+
return self._delegate.next_page_token(
|
|
58
|
+
response, last_page_size, last_record, last_page_token_value
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def get_page_size(self) -> Optional[int]:
|
|
62
|
+
return self._delegate.get_page_size()
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def initial_token(self) -> Optional[Any]:
|
|
66
|
+
return self._delegate.initial_token
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from dataclasses import InitVar, dataclass
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Any, List, Literal, Mapping, MutableMapping, Optional, Union
|
|
8
|
+
|
|
9
|
+
from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
|
|
10
|
+
from airbyte_cdk.sources.types import Config
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RequestOptionType(Enum):
|
|
14
|
+
"""
|
|
15
|
+
Describes where to set a value on a request
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
request_parameter = "request_parameter"
|
|
19
|
+
header = "header"
|
|
20
|
+
body_data = "body_data"
|
|
21
|
+
body_json = "body_json"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class RequestOption:
|
|
26
|
+
"""
|
|
27
|
+
Describes an option to set on a request
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
field_name (str): Describes the name of the parameter to inject. Mutually exclusive with field_path.
|
|
31
|
+
field_path (list(str)): Describes the path to a nested field as a list of field names.
|
|
32
|
+
Only valid for body_json injection type, and mutually exclusive with field_name.
|
|
33
|
+
inject_into (RequestOptionType): Describes where in the HTTP request to inject the parameter
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
inject_into: RequestOptionType
|
|
37
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
38
|
+
field_name: Optional[Union[InterpolatedString, str]] = None
|
|
39
|
+
field_path: Optional[List[Union[InterpolatedString, str]]] = None
|
|
40
|
+
|
|
41
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
42
|
+
# Validate inputs. We should expect either field_name or field_path, but not both
|
|
43
|
+
if self.field_name is None and self.field_path is None:
|
|
44
|
+
raise ValueError("RequestOption requires either a field_name or field_path")
|
|
45
|
+
|
|
46
|
+
if self.field_name is not None and self.field_path is not None:
|
|
47
|
+
raise ValueError(
|
|
48
|
+
"Only one of field_name or field_path can be provided to RequestOption"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Nested field injection is only supported for body JSON injection
|
|
52
|
+
if self.field_path is not None and self.inject_into != RequestOptionType.body_json:
|
|
53
|
+
raise ValueError(
|
|
54
|
+
"Nested field injection is only supported for body JSON injection. Please use a top-level field_name for other injection types."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Convert field_name and field_path into InterpolatedString objects if they are strings
|
|
58
|
+
if self.field_name is not None:
|
|
59
|
+
self.field_name = InterpolatedString.create(self.field_name, parameters=parameters)
|
|
60
|
+
elif self.field_path is not None:
|
|
61
|
+
self.field_path = [
|
|
62
|
+
InterpolatedString.create(segment, parameters=parameters)
|
|
63
|
+
for segment in self.field_path
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def _is_field_path(self) -> bool:
|
|
68
|
+
"""Returns whether this option is a field path (ie, a nested field)"""
|
|
69
|
+
return self.field_path is not None
|
|
70
|
+
|
|
71
|
+
def inject_into_request(
|
|
72
|
+
self,
|
|
73
|
+
target: MutableMapping[str, Any],
|
|
74
|
+
value: Any,
|
|
75
|
+
config: Config,
|
|
76
|
+
) -> None:
|
|
77
|
+
"""
|
|
78
|
+
Inject a request option value into a target request structure using either field_name or field_path.
|
|
79
|
+
For non-body-json injection, only top-level field names are supported.
|
|
80
|
+
For body-json injection, both field names and nested field paths are supported.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
target: The request structure to inject the value into
|
|
84
|
+
value: The value to inject
|
|
85
|
+
config: The config object to use for interpolation
|
|
86
|
+
"""
|
|
87
|
+
if self._is_field_path:
|
|
88
|
+
if self.inject_into != RequestOptionType.body_json:
|
|
89
|
+
raise ValueError(
|
|
90
|
+
"Nested field injection is only supported for body JSON injection. Please use a top-level field_name for other injection types."
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
assert self.field_path is not None # for type checker
|
|
94
|
+
current = target
|
|
95
|
+
# Convert path segments into strings, evaluating any interpolated segments
|
|
96
|
+
# Example: ["data", "{{ config[user_type] }}", "id"] -> ["data", "admin", "id"]
|
|
97
|
+
*path_parts, final_key = [
|
|
98
|
+
str(
|
|
99
|
+
segment.eval(config=config)
|
|
100
|
+
if isinstance(segment, InterpolatedString)
|
|
101
|
+
else segment
|
|
102
|
+
)
|
|
103
|
+
for segment in self.field_path
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
# Build a nested dictionary structure and set the final value at the deepest level
|
|
107
|
+
for part in path_parts:
|
|
108
|
+
current = current.setdefault(part, {})
|
|
109
|
+
current[final_key] = value
|
|
110
|
+
else:
|
|
111
|
+
# For non-nested fields, evaluate the field name if it's an interpolated string
|
|
112
|
+
key = (
|
|
113
|
+
self.field_name.eval(config=config)
|
|
114
|
+
if isinstance(self.field_name, InterpolatedString)
|
|
115
|
+
else self.field_name
|
|
116
|
+
)
|
|
117
|
+
target[str(key)] = value
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from airbyte_cdk.sources.declarative.requesters.request_options.datetime_based_request_options_provider import (
|
|
6
|
+
DatetimeBasedRequestOptionsProvider,
|
|
7
|
+
)
|
|
8
|
+
from airbyte_cdk.sources.declarative.requesters.request_options.default_request_options_provider import (
|
|
9
|
+
DefaultRequestOptionsProvider,
|
|
10
|
+
)
|
|
11
|
+
from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_options_provider import (
|
|
12
|
+
InterpolatedRequestOptionsProvider,
|
|
13
|
+
)
|
|
14
|
+
from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
|
|
15
|
+
RequestOptionsProvider,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"DatetimeBasedRequestOptionsProvider",
|
|
20
|
+
"DefaultRequestOptionsProvider",
|
|
21
|
+
"InterpolatedRequestOptionsProvider",
|
|
22
|
+
"RequestOptionsProvider",
|
|
23
|
+
]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from dataclasses import InitVar, dataclass
|
|
6
|
+
from typing import Any, Mapping, MutableMapping, Optional, Union
|
|
7
|
+
|
|
8
|
+
from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
|
|
9
|
+
from airbyte_cdk.sources.declarative.requesters.request_option import (
|
|
10
|
+
RequestOption,
|
|
11
|
+
RequestOptionType,
|
|
12
|
+
)
|
|
13
|
+
from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
|
|
14
|
+
RequestOptionsProvider,
|
|
15
|
+
)
|
|
16
|
+
from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class DatetimeBasedRequestOptionsProvider(RequestOptionsProvider):
|
|
21
|
+
"""
|
|
22
|
+
Request options provider that extracts fields from the stream_slice and injects them into the respective location in the
|
|
23
|
+
outbound request being made
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
config: Config
|
|
27
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
28
|
+
start_time_option: Optional[RequestOption] = None
|
|
29
|
+
end_time_option: Optional[RequestOption] = None
|
|
30
|
+
partition_field_start: Optional[str] = None
|
|
31
|
+
partition_field_end: Optional[str] = None
|
|
32
|
+
|
|
33
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
34
|
+
self._partition_field_start = InterpolatedString.create(
|
|
35
|
+
self.partition_field_start or "start_time", parameters=parameters
|
|
36
|
+
)
|
|
37
|
+
self._partition_field_end = InterpolatedString.create(
|
|
38
|
+
self.partition_field_end or "end_time", parameters=parameters
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def get_request_params(
|
|
42
|
+
self,
|
|
43
|
+
*,
|
|
44
|
+
stream_state: Optional[StreamState] = None,
|
|
45
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
46
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
47
|
+
) -> Mapping[str, Any]:
|
|
48
|
+
return self._get_request_options(RequestOptionType.request_parameter, stream_slice)
|
|
49
|
+
|
|
50
|
+
def get_request_headers(
|
|
51
|
+
self,
|
|
52
|
+
*,
|
|
53
|
+
stream_state: Optional[StreamState] = None,
|
|
54
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
55
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
56
|
+
) -> Mapping[str, Any]:
|
|
57
|
+
return self._get_request_options(RequestOptionType.header, stream_slice)
|
|
58
|
+
|
|
59
|
+
def get_request_body_data(
|
|
60
|
+
self,
|
|
61
|
+
*,
|
|
62
|
+
stream_state: Optional[StreamState] = None,
|
|
63
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
64
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
65
|
+
) -> Union[Mapping[str, Any], str]:
|
|
66
|
+
return self._get_request_options(RequestOptionType.body_data, stream_slice)
|
|
67
|
+
|
|
68
|
+
def get_request_body_json(
|
|
69
|
+
self,
|
|
70
|
+
*,
|
|
71
|
+
stream_state: Optional[StreamState] = None,
|
|
72
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
73
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
74
|
+
) -> Mapping[str, Any]:
|
|
75
|
+
return self._get_request_options(RequestOptionType.body_json, stream_slice)
|
|
76
|
+
|
|
77
|
+
def _get_request_options(
|
|
78
|
+
self, option_type: RequestOptionType, stream_slice: Optional[StreamSlice]
|
|
79
|
+
) -> Mapping[str, Any]:
|
|
80
|
+
options: MutableMapping[str, Any] = {}
|
|
81
|
+
if not stream_slice:
|
|
82
|
+
return options
|
|
83
|
+
|
|
84
|
+
if self.start_time_option and self.start_time_option.inject_into == option_type:
|
|
85
|
+
start_time_value = stream_slice.get(self._partition_field_start.eval(self.config))
|
|
86
|
+
self.start_time_option.inject_into_request(options, start_time_value, self.config)
|
|
87
|
+
|
|
88
|
+
if self.end_time_option and self.end_time_option.inject_into == option_type:
|
|
89
|
+
end_time_value = stream_slice.get(self._partition_field_end.eval(self.config))
|
|
90
|
+
self.end_time_option.inject_into_request(options, end_time_value, self.config)
|
|
91
|
+
|
|
92
|
+
return options
|
airbyte_cdk/sources/declarative/requesters/request_options/default_request_options_provider.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from dataclasses import InitVar, dataclass
|
|
6
|
+
from typing import Any, Mapping, Optional, Union
|
|
7
|
+
|
|
8
|
+
from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
|
|
9
|
+
RequestOptionsProvider,
|
|
10
|
+
)
|
|
11
|
+
from airbyte_cdk.sources.types import StreamSlice, StreamState
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class DefaultRequestOptionsProvider(RequestOptionsProvider):
|
|
16
|
+
"""
|
|
17
|
+
Request options provider that extracts fields from the stream_slice and injects them into the respective location in the
|
|
18
|
+
outbound request being made
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
22
|
+
|
|
23
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
def get_request_params(
|
|
27
|
+
self,
|
|
28
|
+
*,
|
|
29
|
+
stream_state: Optional[StreamState] = None,
|
|
30
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
31
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
32
|
+
) -> Mapping[str, Any]:
|
|
33
|
+
return {}
|
|
34
|
+
|
|
35
|
+
def get_request_headers(
|
|
36
|
+
self,
|
|
37
|
+
*,
|
|
38
|
+
stream_state: Optional[StreamState] = None,
|
|
39
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
40
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
41
|
+
) -> Mapping[str, Any]:
|
|
42
|
+
return {}
|
|
43
|
+
|
|
44
|
+
def get_request_body_data(
|
|
45
|
+
self,
|
|
46
|
+
*,
|
|
47
|
+
stream_state: Optional[StreamState] = None,
|
|
48
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
49
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
50
|
+
) -> Union[Mapping[str, Any], str]:
|
|
51
|
+
return {}
|
|
52
|
+
|
|
53
|
+
def get_request_body_json(
|
|
54
|
+
self,
|
|
55
|
+
*,
|
|
56
|
+
stream_state: Optional[StreamState] = None,
|
|
57
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
58
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
59
|
+
) -> Mapping[str, Any]:
|
|
60
|
+
return {}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from dataclasses import InitVar, dataclass, field
|
|
6
|
+
from typing import Any, Mapping, Optional, Union
|
|
7
|
+
|
|
8
|
+
from airbyte_cdk.sources.declarative.interpolation.interpolated_nested_mapping import (
|
|
9
|
+
InterpolatedNestedMapping,
|
|
10
|
+
NestedMapping,
|
|
11
|
+
)
|
|
12
|
+
from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
|
|
13
|
+
from airbyte_cdk.sources.types import Config, StreamSlice
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class InterpolatedNestedRequestInputProvider:
|
|
18
|
+
"""
|
|
19
|
+
Helper class that generically performs string interpolation on a provided deeply nested dictionary or string input
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
23
|
+
request_inputs: Optional[Union[str, NestedMapping]] = field(default=None)
|
|
24
|
+
config: Config = field(default_factory=dict)
|
|
25
|
+
_interpolator: Optional[Union[InterpolatedString, InterpolatedNestedMapping]] = field(
|
|
26
|
+
init=False, repr=False, default=None
|
|
27
|
+
)
|
|
28
|
+
_request_inputs: Optional[Union[str, NestedMapping]] = field(
|
|
29
|
+
init=False, repr=False, default=None
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
33
|
+
self._request_inputs = self.request_inputs or {}
|
|
34
|
+
if isinstance(self._request_inputs, str):
|
|
35
|
+
self._interpolator = InterpolatedString(
|
|
36
|
+
self._request_inputs, default="", parameters=parameters
|
|
37
|
+
)
|
|
38
|
+
else:
|
|
39
|
+
self._interpolator = InterpolatedNestedMapping(
|
|
40
|
+
self._request_inputs, parameters=parameters
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def eval_request_inputs(
|
|
44
|
+
self,
|
|
45
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
46
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
47
|
+
) -> Mapping[str, Any]:
|
|
48
|
+
"""
|
|
49
|
+
Returns the request inputs to set on an outgoing HTTP request
|
|
50
|
+
|
|
51
|
+
:param stream_slice: The stream slice
|
|
52
|
+
:param next_page_token: The pagination token
|
|
53
|
+
:return: The request inputs to set on an outgoing HTTP request
|
|
54
|
+
"""
|
|
55
|
+
kwargs = {
|
|
56
|
+
"stream_slice": stream_slice,
|
|
57
|
+
"next_page_token": next_page_token,
|
|
58
|
+
}
|
|
59
|
+
return self._interpolator.eval(self.config, **kwargs) # type: ignore # self._interpolator is always initialized with a value and will not be None
|
airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from dataclasses import InitVar, dataclass, field
|
|
6
|
+
from typing import Any, Mapping, Optional, Tuple, Type, Union
|
|
7
|
+
|
|
8
|
+
from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping
|
|
9
|
+
from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
|
|
10
|
+
from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class InterpolatedRequestInputProvider:
|
|
15
|
+
"""
|
|
16
|
+
Helper class that generically performs string interpolation on the provided dictionary or string input
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
20
|
+
request_inputs: Optional[Union[str, Mapping[str, str]]] = field(default=None)
|
|
21
|
+
config: Config = field(default_factory=dict)
|
|
22
|
+
_interpolator: Optional[Union[InterpolatedString, InterpolatedMapping]] = field(
|
|
23
|
+
init=False, repr=False, default=None
|
|
24
|
+
)
|
|
25
|
+
_request_inputs: Optional[Union[str, Mapping[str, str]]] = field(
|
|
26
|
+
init=False, repr=False, default=None
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
30
|
+
self._request_inputs = self.request_inputs or {}
|
|
31
|
+
if isinstance(self._request_inputs, str):
|
|
32
|
+
self._interpolator = InterpolatedString(
|
|
33
|
+
self._request_inputs, default="", parameters=parameters
|
|
34
|
+
)
|
|
35
|
+
else:
|
|
36
|
+
self._interpolator = InterpolatedMapping(self._request_inputs, parameters=parameters)
|
|
37
|
+
|
|
38
|
+
def eval_request_inputs(
|
|
39
|
+
self,
|
|
40
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
41
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
42
|
+
valid_key_types: Optional[Tuple[Type[Any]]] = None,
|
|
43
|
+
valid_value_types: Optional[Tuple[Type[Any], ...]] = None,
|
|
44
|
+
) -> Mapping[str, Any]:
|
|
45
|
+
"""
|
|
46
|
+
Returns the request inputs to set on an outgoing HTTP request
|
|
47
|
+
|
|
48
|
+
:param stream_slice: The stream slice
|
|
49
|
+
:param next_page_token: The pagination token
|
|
50
|
+
:param valid_key_types: A tuple of types that the interpolator should allow
|
|
51
|
+
:param valid_value_types: A tuple of types that the interpolator should allow
|
|
52
|
+
:return: The request inputs to set on an outgoing HTTP request
|
|
53
|
+
"""
|
|
54
|
+
kwargs = {
|
|
55
|
+
"stream_slice": stream_slice,
|
|
56
|
+
"next_page_token": next_page_token,
|
|
57
|
+
}
|
|
58
|
+
interpolated_value = self._interpolator.eval( # type: ignore # self._interpolator is always initialized with a value and will not be None
|
|
59
|
+
self.config,
|
|
60
|
+
valid_key_types=valid_key_types,
|
|
61
|
+
valid_value_types=valid_value_types,
|
|
62
|
+
**kwargs,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if isinstance(interpolated_value, dict):
|
|
66
|
+
non_null_tokens = {k: v for k, v in interpolated_value.items() if v is not None}
|
|
67
|
+
return non_null_tokens
|
|
68
|
+
return interpolated_value # type: ignore[no-any-return]
|