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,29 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from airbyte_cdk.sources.declarative.partition_routers.async_job_partition_router import (
|
|
6
|
+
AsyncJobPartitionRouter,
|
|
7
|
+
)
|
|
8
|
+
from airbyte_cdk.sources.declarative.partition_routers.cartesian_product_stream_slicer import (
|
|
9
|
+
CartesianProductStreamSlicer,
|
|
10
|
+
)
|
|
11
|
+
from airbyte_cdk.sources.declarative.partition_routers.list_partition_router import (
|
|
12
|
+
ListPartitionRouter,
|
|
13
|
+
)
|
|
14
|
+
from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter
|
|
15
|
+
from airbyte_cdk.sources.declarative.partition_routers.single_partition_router import (
|
|
16
|
+
SinglePartitionRouter,
|
|
17
|
+
)
|
|
18
|
+
from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import (
|
|
19
|
+
SubstreamPartitionRouter,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"AsyncJobPartitionRouter",
|
|
24
|
+
"CartesianProductStreamSlicer",
|
|
25
|
+
"ListPartitionRouter",
|
|
26
|
+
"SinglePartitionRouter",
|
|
27
|
+
"SubstreamPartitionRouter",
|
|
28
|
+
"PartitionRouter",
|
|
29
|
+
]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
|
2
|
+
|
|
3
|
+
from dataclasses import InitVar, dataclass, field
|
|
4
|
+
from typing import Any, Callable, Iterable, Mapping, Optional
|
|
5
|
+
|
|
6
|
+
from airbyte_cdk.models import FailureType
|
|
7
|
+
from airbyte_cdk.sources.declarative.async_job.job import AsyncJob
|
|
8
|
+
from airbyte_cdk.sources.declarative.async_job.job_orchestrator import (
|
|
9
|
+
AsyncJobOrchestrator,
|
|
10
|
+
)
|
|
11
|
+
from airbyte_cdk.sources.declarative.partition_routers.single_partition_router import (
|
|
12
|
+
SinglePartitionRouter,
|
|
13
|
+
)
|
|
14
|
+
from airbyte_cdk.sources.streams.concurrent.partitions.stream_slicer import StreamSlicer
|
|
15
|
+
from airbyte_cdk.sources.types import Config, StreamSlice
|
|
16
|
+
from airbyte_cdk.utils.traced_exception import AirbyteTracedException
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class AsyncJobPartitionRouter(StreamSlicer):
|
|
21
|
+
"""
|
|
22
|
+
Partition router that creates async jobs in a source API, periodically polls for job
|
|
23
|
+
completion, and supplies the completed job URL locations as stream slices so that
|
|
24
|
+
records can be extracted.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
config: Config
|
|
28
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
29
|
+
job_orchestrator_factory: Callable[[Iterable[StreamSlice]], AsyncJobOrchestrator]
|
|
30
|
+
stream_slicer: StreamSlicer = field(
|
|
31
|
+
default_factory=lambda: SinglePartitionRouter(parameters={})
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
35
|
+
self._job_orchestrator_factory = self.job_orchestrator_factory
|
|
36
|
+
self._job_orchestrator: Optional[AsyncJobOrchestrator] = None
|
|
37
|
+
self._parameters = parameters
|
|
38
|
+
|
|
39
|
+
def stream_slices(self) -> Iterable[StreamSlice]:
|
|
40
|
+
slices = self.stream_slicer.stream_slices()
|
|
41
|
+
self._job_orchestrator = self._job_orchestrator_factory(slices)
|
|
42
|
+
|
|
43
|
+
for completed_partition in self._job_orchestrator.create_and_get_completed_partitions():
|
|
44
|
+
yield StreamSlice(
|
|
45
|
+
partition=dict(completed_partition.stream_slice.partition),
|
|
46
|
+
cursor_slice=completed_partition.stream_slice.cursor_slice,
|
|
47
|
+
extra_fields={"jobs": list(completed_partition.jobs)},
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def fetch_records(self, async_jobs: Iterable[AsyncJob]) -> Iterable[Mapping[str, Any]]:
|
|
51
|
+
"""
|
|
52
|
+
This method of fetching records extends beyond what a PartitionRouter/StreamSlicer should
|
|
53
|
+
be responsible for. However, this was added in because the JobOrchestrator is required to
|
|
54
|
+
retrieve records. And without defining fetch_records() on this class, we're stuck with either
|
|
55
|
+
passing the JobOrchestrator to the AsyncRetriever or storing it on multiple classes.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
if not self._job_orchestrator:
|
|
59
|
+
raise AirbyteTracedException(
|
|
60
|
+
message="Invalid state within AsyncJobRetriever. Please contact Airbyte Support",
|
|
61
|
+
internal_message="AsyncPartitionRepository is expected to be accessed only after `stream_slices`",
|
|
62
|
+
failure_type=FailureType.system_error,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return self._job_orchestrator.fetch_records(async_jobs=async_jobs)
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
import itertools
|
|
6
|
+
import logging
|
|
7
|
+
from collections import ChainMap
|
|
8
|
+
from collections.abc import Callable
|
|
9
|
+
from dataclasses import InitVar, dataclass
|
|
10
|
+
from typing import Any, Iterable, List, Mapping, Optional
|
|
11
|
+
|
|
12
|
+
from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter
|
|
13
|
+
from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import (
|
|
14
|
+
SubstreamPartitionRouter,
|
|
15
|
+
)
|
|
16
|
+
from airbyte_cdk.sources.types import StreamSlice, StreamState
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def check_for_substream_in_slicers(
|
|
20
|
+
slicers: Iterable[PartitionRouter], log_warning: Callable[[str], None]
|
|
21
|
+
) -> None:
|
|
22
|
+
"""
|
|
23
|
+
Recursively checks for the presence of SubstreamPartitionRouter within slicers.
|
|
24
|
+
Logs a warning if a SubstreamPartitionRouter is found within a CartesianProductStreamSlicer.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
slicers (Iterable[PartitionRouter]): The list of slicers to check.
|
|
28
|
+
log_warning (Callable): Logging function to record warnings.
|
|
29
|
+
"""
|
|
30
|
+
for slicer in slicers:
|
|
31
|
+
if isinstance(slicer, SubstreamPartitionRouter):
|
|
32
|
+
log_warning("Parent state handling is not supported for CartesianProductStreamSlicer.")
|
|
33
|
+
return
|
|
34
|
+
elif isinstance(slicer, CartesianProductStreamSlicer):
|
|
35
|
+
# Recursively check sub-slicers within CartesianProductStreamSlicer
|
|
36
|
+
check_for_substream_in_slicers(slicer.stream_slicers, log_warning)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class CartesianProductStreamSlicer(PartitionRouter):
|
|
41
|
+
"""
|
|
42
|
+
Stream slicers that iterates over the cartesian product of input stream slicers
|
|
43
|
+
Given 2 stream slicers with the following slices:
|
|
44
|
+
A: [{"i": 0}, {"i": 1}, {"i": 2}]
|
|
45
|
+
B: [{"s": "hello"}, {"s": "world"}]
|
|
46
|
+
the resulting stream slices are
|
|
47
|
+
[
|
|
48
|
+
{"i": 0, "s": "hello"},
|
|
49
|
+
{"i": 0, "s": "world"},
|
|
50
|
+
{"i": 1, "s": "hello"},
|
|
51
|
+
{"i": 1, "s": "world"},
|
|
52
|
+
{"i": 2, "s": "hello"},
|
|
53
|
+
{"i": 2, "s": "world"},
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
Attributes:
|
|
57
|
+
stream_slicers (List[PartitionRouter]): Underlying stream slicers. The RequestOptions (e.g: Request headers, parameters, etc..) returned by this slicer are the combination of the RequestOptions of its input slicers. If there are conflicts e.g: two slicers define the same header or request param, the conflict is resolved by taking the value from the first slicer, where ordering is determined by the order in which slicers were input to this composite slicer.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
stream_slicers: List[PartitionRouter]
|
|
61
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
62
|
+
|
|
63
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
64
|
+
check_for_substream_in_slicers(self.stream_slicers, self.logger.warning)
|
|
65
|
+
|
|
66
|
+
def get_request_params(
|
|
67
|
+
self,
|
|
68
|
+
*,
|
|
69
|
+
stream_state: Optional[StreamState] = None,
|
|
70
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
71
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
72
|
+
) -> Mapping[str, Any]:
|
|
73
|
+
return dict(
|
|
74
|
+
ChainMap(
|
|
75
|
+
*[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
|
|
76
|
+
s.get_request_params(
|
|
77
|
+
stream_state=stream_state,
|
|
78
|
+
stream_slice=stream_slice,
|
|
79
|
+
next_page_token=next_page_token,
|
|
80
|
+
)
|
|
81
|
+
for s in self.stream_slicers
|
|
82
|
+
]
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
def get_request_headers(
|
|
87
|
+
self,
|
|
88
|
+
*,
|
|
89
|
+
stream_state: Optional[StreamState] = None,
|
|
90
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
91
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
92
|
+
) -> Mapping[str, Any]:
|
|
93
|
+
return dict(
|
|
94
|
+
ChainMap(
|
|
95
|
+
*[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
|
|
96
|
+
s.get_request_headers(
|
|
97
|
+
stream_state=stream_state,
|
|
98
|
+
stream_slice=stream_slice,
|
|
99
|
+
next_page_token=next_page_token,
|
|
100
|
+
)
|
|
101
|
+
for s in self.stream_slicers
|
|
102
|
+
]
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
def get_request_body_data(
|
|
107
|
+
self,
|
|
108
|
+
*,
|
|
109
|
+
stream_state: Optional[StreamState] = None,
|
|
110
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
111
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
112
|
+
) -> Mapping[str, Any]:
|
|
113
|
+
return dict(
|
|
114
|
+
ChainMap(
|
|
115
|
+
*[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
|
|
116
|
+
s.get_request_body_data(
|
|
117
|
+
stream_state=stream_state,
|
|
118
|
+
stream_slice=stream_slice,
|
|
119
|
+
next_page_token=next_page_token,
|
|
120
|
+
)
|
|
121
|
+
for s in self.stream_slicers
|
|
122
|
+
]
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
def get_request_body_json(
|
|
127
|
+
self,
|
|
128
|
+
*,
|
|
129
|
+
stream_state: Optional[StreamState] = None,
|
|
130
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
131
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
132
|
+
) -> Mapping[str, Any]:
|
|
133
|
+
return dict(
|
|
134
|
+
ChainMap(
|
|
135
|
+
*[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
|
|
136
|
+
s.get_request_body_json(
|
|
137
|
+
stream_state=stream_state,
|
|
138
|
+
stream_slice=stream_slice,
|
|
139
|
+
next_page_token=next_page_token,
|
|
140
|
+
)
|
|
141
|
+
for s in self.stream_slicers
|
|
142
|
+
]
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
def stream_slices(self) -> Iterable[StreamSlice]:
|
|
147
|
+
sub_slices = (s.stream_slices() for s in self.stream_slicers)
|
|
148
|
+
product = itertools.product(*sub_slices)
|
|
149
|
+
for stream_slice_tuple in product:
|
|
150
|
+
partition = dict(ChainMap(*[s.partition for s in stream_slice_tuple])) # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
|
|
151
|
+
cursor_slices = [s.cursor_slice for s in stream_slice_tuple if s.cursor_slice]
|
|
152
|
+
if len(cursor_slices) > 1:
|
|
153
|
+
raise ValueError(
|
|
154
|
+
f"There should only be a single cursor slice. Found {cursor_slices}"
|
|
155
|
+
)
|
|
156
|
+
if cursor_slices:
|
|
157
|
+
cursor_slice = cursor_slices[0]
|
|
158
|
+
else:
|
|
159
|
+
cursor_slice = {}
|
|
160
|
+
yield StreamSlice(partition=partition, cursor_slice=cursor_slice)
|
|
161
|
+
|
|
162
|
+
def set_initial_state(self, stream_state: StreamState) -> None:
|
|
163
|
+
"""
|
|
164
|
+
Parent stream states are not supported for cartesian product stream slicer
|
|
165
|
+
"""
|
|
166
|
+
pass
|
|
167
|
+
|
|
168
|
+
def get_stream_state(self) -> Optional[Mapping[str, StreamState]]:
|
|
169
|
+
"""
|
|
170
|
+
Parent stream states are not supported for cartesian product stream slicer
|
|
171
|
+
"""
|
|
172
|
+
pass
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def logger(self) -> logging.Logger:
|
|
176
|
+
return logging.getLogger("airbyte.CartesianProductStreamSlicer")
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from dataclasses import InitVar, dataclass
|
|
6
|
+
from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union
|
|
7
|
+
|
|
8
|
+
from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
|
|
9
|
+
from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter
|
|
10
|
+
from airbyte_cdk.sources.declarative.requesters.request_option import (
|
|
11
|
+
RequestOption,
|
|
12
|
+
RequestOptionType,
|
|
13
|
+
)
|
|
14
|
+
from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class ListPartitionRouter(PartitionRouter):
|
|
19
|
+
"""
|
|
20
|
+
Partition router that iterates over the values of a list
|
|
21
|
+
If values is a string, then evaluate it as literal and assert the resulting literal is a list
|
|
22
|
+
|
|
23
|
+
Attributes:
|
|
24
|
+
values (Union[str, List[str]]): The values to iterate over
|
|
25
|
+
cursor_field (Union[InterpolatedString, str]): The name of the cursor field
|
|
26
|
+
config (Config): The user-provided configuration as specified by the source's spec
|
|
27
|
+
request_option (Optional[RequestOption]): The request option to configure the HTTP request
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
values: Union[str, List[str]]
|
|
31
|
+
cursor_field: Union[InterpolatedString, str]
|
|
32
|
+
config: Config
|
|
33
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
34
|
+
request_option: Optional[RequestOption] = None
|
|
35
|
+
|
|
36
|
+
def __post_init__(self, parameters: Mapping[str, Any]) -> None:
|
|
37
|
+
if isinstance(self.values, str):
|
|
38
|
+
self.values = InterpolatedString.create(self.values, parameters=parameters).eval(
|
|
39
|
+
self.config
|
|
40
|
+
)
|
|
41
|
+
self._cursor_field = (
|
|
42
|
+
InterpolatedString(string=self.cursor_field, parameters=parameters)
|
|
43
|
+
if isinstance(self.cursor_field, str)
|
|
44
|
+
else self.cursor_field
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
self._cursor = None
|
|
48
|
+
|
|
49
|
+
def get_request_params(
|
|
50
|
+
self,
|
|
51
|
+
stream_state: Optional[StreamState] = None,
|
|
52
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
53
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
54
|
+
) -> Mapping[str, Any]:
|
|
55
|
+
# Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response
|
|
56
|
+
return self._get_request_option(RequestOptionType.request_parameter, stream_slice)
|
|
57
|
+
|
|
58
|
+
def get_request_headers(
|
|
59
|
+
self,
|
|
60
|
+
stream_state: Optional[StreamState] = None,
|
|
61
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
62
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
63
|
+
) -> Mapping[str, Any]:
|
|
64
|
+
# Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response
|
|
65
|
+
return self._get_request_option(RequestOptionType.header, stream_slice)
|
|
66
|
+
|
|
67
|
+
def get_request_body_data(
|
|
68
|
+
self,
|
|
69
|
+
stream_state: Optional[StreamState] = None,
|
|
70
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
71
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
72
|
+
) -> Mapping[str, Any]:
|
|
73
|
+
# Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response
|
|
74
|
+
return self._get_request_option(RequestOptionType.body_data, stream_slice)
|
|
75
|
+
|
|
76
|
+
def get_request_body_json(
|
|
77
|
+
self,
|
|
78
|
+
stream_state: Optional[StreamState] = None,
|
|
79
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
80
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
81
|
+
) -> Mapping[str, Any]:
|
|
82
|
+
# Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response
|
|
83
|
+
return self._get_request_option(RequestOptionType.body_json, stream_slice)
|
|
84
|
+
|
|
85
|
+
def stream_slices(self) -> Iterable[StreamSlice]:
|
|
86
|
+
return [
|
|
87
|
+
StreamSlice(
|
|
88
|
+
partition={self._cursor_field.eval(self.config): slice_value}, cursor_slice={}
|
|
89
|
+
)
|
|
90
|
+
for slice_value in self.values
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
def _get_request_option(
|
|
94
|
+
self, request_option_type: RequestOptionType, stream_slice: Optional[StreamSlice]
|
|
95
|
+
) -> Mapping[str, Any]:
|
|
96
|
+
if (
|
|
97
|
+
self.request_option
|
|
98
|
+
and self.request_option.inject_into == request_option_type
|
|
99
|
+
and stream_slice
|
|
100
|
+
):
|
|
101
|
+
slice_value = stream_slice.get(self._cursor_field.eval(self.config))
|
|
102
|
+
if slice_value:
|
|
103
|
+
options: MutableMapping[str, Any] = {}
|
|
104
|
+
self.request_option.inject_into_request(options, slice_value, self.config)
|
|
105
|
+
return options
|
|
106
|
+
else:
|
|
107
|
+
return {}
|
|
108
|
+
else:
|
|
109
|
+
return {}
|
|
110
|
+
|
|
111
|
+
def set_initial_state(self, stream_state: StreamState) -> None:
|
|
112
|
+
"""
|
|
113
|
+
ListPartitionRouter doesn't have parent streams
|
|
114
|
+
"""
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
def get_stream_state(self) -> Optional[Mapping[str, StreamState]]:
|
|
118
|
+
"""
|
|
119
|
+
ListPartitionRouter doesn't have parent streams
|
|
120
|
+
"""
|
|
121
|
+
pass
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2024 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from abc import abstractmethod
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Mapping, Optional
|
|
8
|
+
|
|
9
|
+
from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer
|
|
10
|
+
from airbyte_cdk.sources.types import StreamState
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class PartitionRouter(StreamSlicer):
|
|
15
|
+
"""
|
|
16
|
+
Base class for partition routers.
|
|
17
|
+
Methods:
|
|
18
|
+
set_parent_state(stream_state): Set the state of the parent streams.
|
|
19
|
+
get_parent_state(): Get the state of the parent streams.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
@abstractmethod
|
|
23
|
+
def set_initial_state(self, stream_state: StreamState) -> None:
|
|
24
|
+
"""
|
|
25
|
+
Set the state of the parent streams.
|
|
26
|
+
|
|
27
|
+
This method should only be implemented if the slicer is based on some parent stream and needs to read this stream
|
|
28
|
+
incrementally using the state.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
stream_state (StreamState): The state of the streams to be set. The expected format is a dictionary that includes
|
|
32
|
+
'parent_state' which is a dictionary of parent state names to their corresponding state.
|
|
33
|
+
Example:
|
|
34
|
+
{
|
|
35
|
+
"parent_state": {
|
|
36
|
+
"parent_stream_name_1": { ... },
|
|
37
|
+
"parent_stream_name_2": { ... },
|
|
38
|
+
...
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
@abstractmethod
|
|
44
|
+
def get_stream_state(self) -> Optional[Mapping[str, StreamState]]:
|
|
45
|
+
"""
|
|
46
|
+
Get the state of the parent streams.
|
|
47
|
+
|
|
48
|
+
This method should only be implemented if the slicer is based on some parent stream and needs to read this stream
|
|
49
|
+
incrementally using the state.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Optional[Mapping[str, StreamState]]: The current state of the parent streams in a dictionary format.
|
|
53
|
+
The returned format will be:
|
|
54
|
+
{
|
|
55
|
+
"parent_stream_name1": {
|
|
56
|
+
"last_updated": "2023-05-27T00:00:00Z"
|
|
57
|
+
},
|
|
58
|
+
"parent_stream_name2": {
|
|
59
|
+
"last_updated": "2023-05-27T00:00:00Z"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
"""
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
from dataclasses import InitVar, dataclass
|
|
6
|
+
from typing import Any, Iterable, Mapping, Optional
|
|
7
|
+
|
|
8
|
+
from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter
|
|
9
|
+
from airbyte_cdk.sources.types import StreamSlice, StreamState
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class SinglePartitionRouter(PartitionRouter):
|
|
14
|
+
"""Partition router returning only a stream slice"""
|
|
15
|
+
|
|
16
|
+
parameters: InitVar[Mapping[str, Any]]
|
|
17
|
+
|
|
18
|
+
def get_request_params(
|
|
19
|
+
self,
|
|
20
|
+
stream_state: Optional[StreamState] = None,
|
|
21
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
22
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
23
|
+
) -> Mapping[str, Any]:
|
|
24
|
+
return {}
|
|
25
|
+
|
|
26
|
+
def get_request_headers(
|
|
27
|
+
self,
|
|
28
|
+
stream_state: Optional[StreamState] = None,
|
|
29
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
30
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
31
|
+
) -> Mapping[str, Any]:
|
|
32
|
+
return {}
|
|
33
|
+
|
|
34
|
+
def get_request_body_data(
|
|
35
|
+
self,
|
|
36
|
+
stream_state: Optional[StreamState] = None,
|
|
37
|
+
stream_slice: Optional[StreamSlice] = None,
|
|
38
|
+
next_page_token: Optional[Mapping[str, Any]] = None,
|
|
39
|
+
) -> Mapping[str, Any]:
|
|
40
|
+
return {}
|
|
41
|
+
|
|
42
|
+
def get_request_body_json(
|
|
43
|
+
self,
|
|
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 {}
|
|
49
|
+
|
|
50
|
+
def stream_slices(self) -> Iterable[StreamSlice]:
|
|
51
|
+
yield StreamSlice(partition={}, cursor_slice={})
|
|
52
|
+
|
|
53
|
+
def set_initial_state(self, stream_state: StreamState) -> None:
|
|
54
|
+
"""
|
|
55
|
+
SinglePartitionRouter doesn't have parent streams
|
|
56
|
+
"""
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
def get_stream_state(self) -> Optional[Mapping[str, StreamState]]:
|
|
60
|
+
"""
|
|
61
|
+
SinglePartitionRouter doesn't have parent streams
|
|
62
|
+
"""
|
|
63
|
+
pass
|