airbyte-cdk 0.40.1__tar.gz → 0.40.3__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/PKG-INFO +1 -1
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/connector_builder/message_grouper.py +6 -1
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/connector_builder/models.py +1 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/declarative_component_schema.yaml +4 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/models/declarative_component_schema.py +4 -0
- airbyte-cdk-0.40.3/airbyte_cdk/utils/datetime_format_inferrer.py +80 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk.egg-info/PKG-INFO +1 -1
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk.egg-info/SOURCES.txt +2 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/setup.py +1 -1
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/connector_builder/test_connector_builder_handler.py +3 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/connector_builder/test_message_grouper.py +8 -6
- airbyte-cdk-0.40.3/unit_tests/utils/test_datetime_format_inferrer.py +53 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/LICENSE.txt +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/README.md +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/config_observation.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/connector.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/connector_builder/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/connector_builder/connector_builder_handler.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/connector_builder/main.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/destinations/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/destinations/destination.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/entrypoint.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/exception_handler.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/logger.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/models/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/models/airbyte_protocol.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/models/well_known_types.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/py.typed +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/abstract_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/config.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/connector_state_manager.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/auth/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/auth/declarative_authenticator.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/auth/oauth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/auth/token.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/checks/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/checks/check_stream.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/checks/connection_checker.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/create_partial.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/datetime/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/datetime/datetime_parser.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/declarative_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/declarative_stream.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/decoders/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/decoders/decoder.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/decoders/json_decoder.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/exceptions.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/extractors/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/extractors/dpath_extractor.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/extractors/http_selector.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/extractors/record_extractor.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/extractors/record_filter.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/extractors/record_selector.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/incremental/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/filters.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/interpolated_string.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/interpolation.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/jinja.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/macros.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/manifest_declarative_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/models/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/parsers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/parsers/class_types_registry.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/parsers/custom_exceptions.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/parsers/default_implementation_registry.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/partition_routers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/response_action.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/error_handlers/response_status.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/http_requester.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/paginator.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/request_option.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/request_options/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/request_path.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/requester.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/retrievers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/retrievers/retriever.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/schema/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/schema/default_schema_loader.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/schema/inline_schema_loader.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/schema/schema_loader.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/spec/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/spec/spec.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/stream_slicers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/stream_slicers/cartesian_product_stream_slicer.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/transformations/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/transformations/add_fields.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/transformations/remove_fields.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/transformations/transformation.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/types.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/yaml_declarative_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/deprecated/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/deprecated/base_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/deprecated/client.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/singer/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/singer/singer_helpers.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/singer/source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/availability_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/core.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/auth/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/auth/core.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/auth/oauth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/auth/token.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/availability_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/exceptions.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/http.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/rate_limiting.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/http/requests_native_auth/token.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/utils/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/streams/utils/stream_helper.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/utils/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/utils/casing.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/utils/catalog_helpers.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/utils/record_helper.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/utils/schema_helpers.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/utils/schema_models.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/utils/transform.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/utils/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/utils/airbyte_secrets_utils.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/utils/event_timing.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/utils/schema_inferrer.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/utils/stream_status_utils.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/utils/traced_exception.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk.egg-info/dependency_links.txt +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk.egg-info/requires.txt +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk.egg-info/top_level.txt +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/pyproject.toml +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/setup.cfg +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/source_declarative_manifest/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/source_declarative_manifest/main.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/connector_builder/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/connector_builder/utils.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/destinations/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/destinations/test_destination.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/singer/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/singer/test_singer_helpers.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/singer/test_singer_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/auth/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/auth/test_oauth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/auth/test_session_token_auth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/auth/test_token_auth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/checks/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/checks/test_check_stream.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/decoders/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/decoders/test_json_decoder.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/external_component.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/extractors/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/extractors/test_dpath_extractor.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/extractors/test_record_filter.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/extractors/test_record_selector.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/incremental/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/incremental/test_datetime_based_cursor.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/interpolation/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/interpolation/test_filters.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/interpolation/test_interpolated_boolean.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/interpolation/test_interpolated_mapping.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/interpolation/test_interpolated_nested_mapping.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/interpolation/test_interpolated_string.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/interpolation/test_jinja.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/interpolation/test_macros.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/parsers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/parsers/test_manifest_component_transformer.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/parsers/test_manifest_reference_resolver.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/parsers/testing_components.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/partition_routers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/partition_routers/test_list_partition_router.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/partition_routers/test_single_partition_router.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/partition_routers/test_substream_partition_router.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_constant_backoff.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_exponential_backoff.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_header_helper.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_time_from_header.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_until_time_from_header.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/test_composite_error_handler.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/test_default_error_handler.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/test_http_response_filter.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/error_handlers/test_response_status.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/paginators/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/paginators/test_cursor_pagination_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/paginators/test_no_paginator.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/paginators/test_page_increment.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/paginators/test_request_option.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/request_options/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/request_options/test_interpolated_request_options_provider.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/test_http_requester.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/requesters/test_interpolated_request_input_provider.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/retrievers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/retrievers/test_simple_retriever.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/schema/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/schema/source_test/SourceTest.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/schema/source_test/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/schema/test_default_schema_loader.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/schema/test_inline_schema_loader.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/schema/test_json_file_schema_loader.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/states/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/stream_slicers/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/stream_slicers/test_cartesian_product_stream_slicer.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/test_create_partial.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/test_declarative_stream.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/test_manifest_declarative_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/declarative/test_yaml_declarative_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/http/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/http/auth/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/http/auth/test_auth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/http/requests_native_auth/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/http/test_availability_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/http/test_http.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/test_availability_strategy.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/streams/test_streams_core.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/test_abstract_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/test_config.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/test_connector_state_manager.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/sources/test_source.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/utils/__init__.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/utils/test_schema_inferrer.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/utils/test_secret_utils.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/utils/test_stream_status_utils.py +0 -0
- {airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/utils/test_traced_exception.py +0 -0
@@ -14,6 +14,7 @@ from airbyte_cdk.entrypoint import AirbyteEntrypoint
|
|
14
14
|
from airbyte_cdk.sources import AbstractSource
|
15
15
|
from airbyte_cdk.sources.declarative.declarative_source import DeclarativeSource
|
16
16
|
from airbyte_cdk.utils import AirbyteTracedException
|
17
|
+
from airbyte_cdk.utils.datetime_format_inferrer import DatetimeFormatInferrer
|
17
18
|
from airbyte_cdk.utils.schema_inferrer import SchemaInferrer
|
18
19
|
from airbyte_protocol.models.airbyte_protocol import (
|
19
20
|
AirbyteControlMessage,
|
@@ -46,6 +47,7 @@ class MessageGrouper:
|
|
46
47
|
if record_limit is not None and not (1 <= record_limit <= 1000):
|
47
48
|
raise ValueError(f"Record limit must be between 1 and 1000. Got {record_limit}")
|
48
49
|
schema_inferrer = SchemaInferrer()
|
50
|
+
datetime_format_inferrer = DatetimeFormatInferrer()
|
49
51
|
|
50
52
|
if record_limit is None:
|
51
53
|
record_limit = self._max_record_limit
|
@@ -58,6 +60,7 @@ class MessageGrouper:
|
|
58
60
|
for message_group in self._get_message_groups(
|
59
61
|
self._read_stream(source, config, configured_catalog),
|
60
62
|
schema_inferrer,
|
63
|
+
datetime_format_inferrer,
|
61
64
|
record_limit,
|
62
65
|
):
|
63
66
|
if isinstance(message_group, AirbyteLogMessage):
|
@@ -80,10 +83,11 @@ class MessageGrouper:
|
|
80
83
|
configured_catalog.streams[0].stream.name
|
81
84
|
), # The connector builder currently only supports reading from a single stream at a time
|
82
85
|
latest_config_update=latest_config_update.connectorConfig.config if latest_config_update else self._clean_config(config),
|
86
|
+
inferred_datetime_formats=datetime_format_inferrer.get_inferred_datetime_formats(),
|
83
87
|
)
|
84
88
|
|
85
89
|
def _get_message_groups(
|
86
|
-
self, messages: Iterator[AirbyteMessage], schema_inferrer: SchemaInferrer, limit: int
|
90
|
+
self, messages: Iterator[AirbyteMessage], schema_inferrer: SchemaInferrer, datetime_format_inferrer: DatetimeFormatInferrer, limit: int
|
87
91
|
) -> Iterable[Union[StreamReadPages, AirbyteControlMessage, AirbyteLogMessage, AirbyteTraceMessage]]:
|
88
92
|
"""
|
89
93
|
Message groups are partitioned according to when request log messages are received. Subsequent response log messages
|
@@ -141,6 +145,7 @@ class MessageGrouper:
|
|
141
145
|
current_page_records.append(message.record.data)
|
142
146
|
records_count += 1
|
143
147
|
schema_inferrer.accumulate(message.record)
|
148
|
+
datetime_format_inferrer.accumulate(message.record)
|
144
149
|
elif message.type == MessageType.CONTROL and message.control.type == OrchestratorType.CONNECTOR_CONFIG:
|
145
150
|
yield message.control
|
146
151
|
else:
|
@@ -27,6 +27,10 @@ properties:
|
|
27
27
|
type: object
|
28
28
|
spec:
|
29
29
|
"$ref": "#/definitions/Spec"
|
30
|
+
metadata:
|
31
|
+
type: object
|
32
|
+
description: For internal Airbyte use only - DO NOT modify manually. Used by consumers of declarative manifests for storing related metadata.
|
33
|
+
additionalProperties: true
|
30
34
|
additionalProperties: false
|
31
35
|
definitions:
|
32
36
|
AddedFieldDefinition:
|
@@ -1095,6 +1095,10 @@ class DeclarativeSource(BaseModel):
|
|
1095
1095
|
schemas: Optional[Schemas] = None
|
1096
1096
|
definitions: Optional[Dict[str, Any]] = None
|
1097
1097
|
spec: Optional[Spec] = None
|
1098
|
+
metadata: Optional[Dict[str, Any]] = Field(
|
1099
|
+
None,
|
1100
|
+
description="For internal Airbyte use only - DO NOT modify manually. Used by consumers of declarative manifests for storing related metadata.",
|
1101
|
+
)
|
1098
1102
|
|
1099
1103
|
|
1100
1104
|
class DeclarativeStream(BaseModel):
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
from typing import Any, Dict, Union
|
6
|
+
|
7
|
+
from airbyte_cdk.models import AirbyteRecordMessage
|
8
|
+
from airbyte_cdk.sources.declarative.datetime.datetime_parser import DatetimeParser
|
9
|
+
|
10
|
+
|
11
|
+
class DatetimeFormatInferrer:
|
12
|
+
"""
|
13
|
+
This class is used to detect toplevel fields in records that might be datetime values, along with the used format.
|
14
|
+
"""
|
15
|
+
|
16
|
+
def __init__(self):
|
17
|
+
self._parser = DatetimeParser()
|
18
|
+
self._datetime_candidates: Union[None, Dict[str, str]] = None
|
19
|
+
self._formats = [
|
20
|
+
"%Y-%m-%d",
|
21
|
+
"%Y-%m-%d %H:%M:%S",
|
22
|
+
"%Y-%m-%d %H:%M:%S.%f+00:00",
|
23
|
+
"%Y-%m-%dT%H:%M:%S.%f%z",
|
24
|
+
"%s",
|
25
|
+
"%d/%m/%Y %H:%M",
|
26
|
+
"%Y-%m",
|
27
|
+
"%d-%m-%Y",
|
28
|
+
"%Y-%m-%dT%H:%M:%SZ",
|
29
|
+
]
|
30
|
+
self._timestamp_heuristic_range = range(1_000_000_000, 2_000_000_000)
|
31
|
+
|
32
|
+
def _can_be_datetime(self, value: Any) -> bool:
|
33
|
+
"""Checks if the value can be a datetime. This is the case if the value is a string or an integer between 1_000_000_000 and 2_000_000_000. This is separate from the format check for performance reasons"""
|
34
|
+
if isinstance(value, str) and (not value.isdecimal() or int(value) in self._timestamp_heuristic_range):
|
35
|
+
return True
|
36
|
+
if isinstance(value, int) and value in self._timestamp_heuristic_range:
|
37
|
+
return True
|
38
|
+
return False
|
39
|
+
|
40
|
+
def _matches_format(self, value: Any, format: str) -> bool:
|
41
|
+
"""Checks if the value matches the format"""
|
42
|
+
try:
|
43
|
+
self._parser.parse(value, format)
|
44
|
+
return True
|
45
|
+
except ValueError:
|
46
|
+
return False
|
47
|
+
|
48
|
+
def _initialize(self, record: AirbyteRecordMessage):
|
49
|
+
"""Initializes the internal state of the class"""
|
50
|
+
self._datetime_candidates = {}
|
51
|
+
for field_name, field_value in record.data.items():
|
52
|
+
if not self._can_be_datetime(field_value):
|
53
|
+
continue
|
54
|
+
for format in self._formats:
|
55
|
+
if self._matches_format(field_value, format):
|
56
|
+
self._datetime_candidates[field_name] = format
|
57
|
+
break
|
58
|
+
|
59
|
+
def _validate(self, record: AirbyteRecordMessage):
|
60
|
+
"""Validates that the record is consistent with the inferred datetime formats"""
|
61
|
+
for candidate_field_name in list(self._datetime_candidates.keys()):
|
62
|
+
candidate_field_format = self._datetime_candidates[candidate_field_name]
|
63
|
+
current_value = record.data.get(candidate_field_name, None)
|
64
|
+
if (
|
65
|
+
current_value is None
|
66
|
+
or not self._can_be_datetime(current_value)
|
67
|
+
or not self._matches_format(current_value, candidate_field_format)
|
68
|
+
):
|
69
|
+
self._datetime_candidates.pop(candidate_field_name)
|
70
|
+
|
71
|
+
def accumulate(self, record: AirbyteRecordMessage):
|
72
|
+
"""Analyzes the record and updates the internal state of candidate datetime fields"""
|
73
|
+
self._initialize(record) if self._datetime_candidates is None else self._validate(record)
|
74
|
+
|
75
|
+
def get_inferred_datetime_formats(self) -> Dict[str, str]:
|
76
|
+
"""
|
77
|
+
Returns the list of candidate datetime fields - the keys are the field names and the values are the inferred datetime formats.
|
78
|
+
For these fields the format was consistent across all visited records.
|
79
|
+
"""
|
80
|
+
return self._datetime_candidates or {}
|
@@ -165,6 +165,7 @@ airbyte_cdk/sources/utils/schema_models.py
|
|
165
165
|
airbyte_cdk/sources/utils/transform.py
|
166
166
|
airbyte_cdk/utils/__init__.py
|
167
167
|
airbyte_cdk/utils/airbyte_secrets_utils.py
|
168
|
+
airbyte_cdk/utils/datetime_format_inferrer.py
|
168
169
|
airbyte_cdk/utils/event_timing.py
|
169
170
|
airbyte_cdk/utils/schema_inferrer.py
|
170
171
|
airbyte_cdk/utils/stream_status_utils.py
|
@@ -267,6 +268,7 @@ unit_tests/sources/streams/http/auth/test_auth.py
|
|
267
268
|
unit_tests/sources/streams/http/requests_native_auth/__init__.py
|
268
269
|
unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py
|
269
270
|
unit_tests/utils/__init__.py
|
271
|
+
unit_tests/utils/test_datetime_format_inferrer.py
|
270
272
|
unit_tests/utils/test_schema_inferrer.py
|
271
273
|
unit_tests/utils/test_secret_utils.py
|
272
274
|
unit_tests/utils/test_stream_status_utils.py
|
@@ -17,7 +17,7 @@ setup(
|
|
17
17
|
name="airbyte-cdk",
|
18
18
|
# The version of the airbyte-cdk package is used at runtime to validate manifests. That validation must be
|
19
19
|
# updated if our semver format changes such as using release candidate versions.
|
20
|
-
version="0.40.
|
20
|
+
version="0.40.3",
|
21
21
|
description="A framework for writing Airbyte Connectors.",
|
22
22
|
long_description=README,
|
23
23
|
long_description_content_type="text/markdown",
|
@@ -354,6 +354,7 @@ def test_read():
|
|
354
354
|
],
|
355
355
|
test_read_limit_reached=False,
|
356
356
|
inferred_schema=None,
|
357
|
+
inferred_datetime_formats=None,
|
357
358
|
latest_config_update={}
|
358
359
|
)
|
359
360
|
|
@@ -368,6 +369,7 @@ def test_read():
|
|
368
369
|
],
|
369
370
|
"test_read_limit_reached": False,
|
370
371
|
"inferred_schema": None,
|
372
|
+
"inferred_datetime_formats": None,
|
371
373
|
"latest_config_update": {}
|
372
374
|
},
|
373
375
|
emitted_at=1,
|
@@ -410,6 +412,7 @@ def test_read_returns_error_response(mock_from_exception):
|
|
410
412
|
slice_descriptor=None, state=None)],
|
411
413
|
test_read_limit_reached=False,
|
412
414
|
inferred_schema=None,
|
415
|
+
inferred_datetime_formats={},
|
413
416
|
latest_config_update={})
|
414
417
|
|
415
418
|
expected_message = AirbyteMessage(
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/unit_tests/connector_builder/test_message_grouper.py
RENAMED
@@ -94,7 +94,8 @@ def test_get_grouped_messages(mock_entrypoint_read):
|
|
94
94
|
"body": {"custom": "field"},
|
95
95
|
}
|
96
96
|
response = {"status_code": 200, "headers": {"field": "value"}, "body": '{"name": "field"}', "http_method": "GET"}
|
97
|
-
expected_schema = {"$schema": "http://json-schema.org/schema#", "properties": {"name": {"type": "string"}}, "type": "object"}
|
97
|
+
expected_schema = {"$schema": "http://json-schema.org/schema#", "properties": {"name": {"type": "string"}, "date": {"type": "string"}}, "type": "object"}
|
98
|
+
expected_datetime_fields = {"date":"%Y-%m-%d"}
|
98
99
|
expected_pages = [
|
99
100
|
StreamReadPages(
|
100
101
|
request=HttpRequest(
|
@@ -105,7 +106,7 @@ def test_get_grouped_messages(mock_entrypoint_read):
|
|
105
106
|
http_method="GET",
|
106
107
|
),
|
107
108
|
response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'),
|
108
|
-
records=[{"name": "Shinobu Kocho"}, {"name": "Muichiro Tokito"}],
|
109
|
+
records=[{"name": "Shinobu Kocho", "date": "2023-03-03"}, {"name": "Muichiro Tokito", "date": "2023-03-04"}],
|
109
110
|
),
|
110
111
|
StreamReadPages(
|
111
112
|
request=HttpRequest(
|
@@ -116,7 +117,7 @@ def test_get_grouped_messages(mock_entrypoint_read):
|
|
116
117
|
http_method="GET",
|
117
118
|
),
|
118
119
|
response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'),
|
119
|
-
records=[{"name": "Mitsuri Kanroji"}],
|
120
|
+
records=[{"name": "Mitsuri Kanroji", "date": "2023-03-05"}],
|
120
121
|
),
|
121
122
|
]
|
122
123
|
|
@@ -124,11 +125,11 @@ def test_get_grouped_messages(mock_entrypoint_read):
|
|
124
125
|
[
|
125
126
|
request_log_message(request),
|
126
127
|
response_log_message(response),
|
127
|
-
record_message("hashiras", {"name": "Shinobu Kocho"}),
|
128
|
-
record_message("hashiras", {"name": "Muichiro Tokito"}),
|
128
|
+
record_message("hashiras", {"name": "Shinobu Kocho", "date": "2023-03-03"}),
|
129
|
+
record_message("hashiras", {"name": "Muichiro Tokito", "date": "2023-03-04"}),
|
129
130
|
request_log_message(request),
|
130
131
|
response_log_message(response),
|
131
|
-
record_message("hashiras", {"name": "Mitsuri Kanroji"}),
|
132
|
+
record_message("hashiras", {"name": "Mitsuri Kanroji", "date": "2023-03-05"}),
|
132
133
|
]
|
133
134
|
))
|
134
135
|
|
@@ -138,6 +139,7 @@ def test_get_grouped_messages(mock_entrypoint_read):
|
|
138
139
|
)
|
139
140
|
|
140
141
|
assert actual_response.inferred_schema == expected_schema
|
142
|
+
assert actual_response.inferred_datetime_formats == expected_datetime_fields
|
141
143
|
|
142
144
|
single_slice = actual_response.slices[0]
|
143
145
|
for i, actual_page in enumerate(single_slice.pages):
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
+
#
|
4
|
+
|
5
|
+
from typing import Dict, List
|
6
|
+
|
7
|
+
import pytest
|
8
|
+
from airbyte_cdk.models.airbyte_protocol import AirbyteRecordMessage
|
9
|
+
from airbyte_cdk.utils.datetime_format_inferrer import DatetimeFormatInferrer
|
10
|
+
|
11
|
+
NOW = 1234567
|
12
|
+
|
13
|
+
|
14
|
+
@pytest.mark.parametrize(
|
15
|
+
"test_name,input_records,expected_candidate_fields",
|
16
|
+
[
|
17
|
+
("empty", [], {}),
|
18
|
+
("simple_match", [{"d": "2022-02-03"}], {"d": "%Y-%m-%d"}),
|
19
|
+
("timestamp_match_integer", [{"d": 1686058051}], {"d": "%s"}),
|
20
|
+
("timestamp_match_string", [{"d": "1686058051"}], {"d": "%s"}),
|
21
|
+
("timestamp_no_match_integer", [{"d": 99}], {}),
|
22
|
+
("timestamp_no_match_string", [{"d": "99999999999999999999"}], {}),
|
23
|
+
("simple_no_match", [{"d": "20220203"}], {}),
|
24
|
+
("multiple_match", [{"d": "2022-02-03", "e": "2022-02-03"}], {"d": "%Y-%m-%d", "e": "%Y-%m-%d"}),
|
25
|
+
(
|
26
|
+
"multiple_no_match",
|
27
|
+
[{"d": "20220203", "r": "ccc", "e": {"something-else": "2023-03-03"}, "s": ["2023-03-03"], "x": False, "y": 123}],
|
28
|
+
{},
|
29
|
+
),
|
30
|
+
("format_1", [{"d": "2022-02-03"}], {"d": "%Y-%m-%d"}),
|
31
|
+
("format_2", [{"d": "2022-02-03 12:34:56"}], {"d": "%Y-%m-%d %H:%M:%S"}),
|
32
|
+
("format_3", [{"d": "2022-02-03 12:34:56.123456+00:00"}], {"d": "%Y-%m-%d %H:%M:%S.%f+00:00"}),
|
33
|
+
("format_4", [{"d": "2022-02-03T12:34:56.123456+0000"}], {"d": "%Y-%m-%dT%H:%M:%S.%f%z"}),
|
34
|
+
("format_4 2", [{"d": "2022-02-03T12:34:56.000Z"}], {"d": "%Y-%m-%dT%H:%M:%S.%f%z"}),
|
35
|
+
("format_4 2", [{"d": "2022-02-03T12:34:56.000000Z"}], {"d": "%Y-%m-%dT%H:%M:%S.%f%z"}),
|
36
|
+
("format_6", [{"d": "03/02/2022 12:34"}], {"d": "%d/%m/%Y %H:%M"}),
|
37
|
+
("format_7", [{"d": "2022-02"}], {"d": "%Y-%m"}),
|
38
|
+
("format_8", [{"d": "03-02-2022"}], {"d": "%d-%m-%Y"}),
|
39
|
+
("limit_down", [{"d": "2022-02-03", "x": "2022-02-03"}, {"d": "2022-02-03", "x": "another thing"}], {"d": "%Y-%m-%d"}),
|
40
|
+
("limit_down all", [{"d": "2022-02-03", "x": "2022-02-03"}, {"d": "also another thing", "x": "another thing"}], {}),
|
41
|
+
("limit_down empty", [{"d": "2022-02-03", "x": "2022-02-03"}, {}], {}),
|
42
|
+
("limit_down unsupported type", [{"d": "2022-02-03"}, {"d": False}], {}),
|
43
|
+
("limit_down complex type", [{"d": "2022-02-03"}, {"d": {"date": "2022-03-03"}}], {}),
|
44
|
+
("limit_down different format", [{"d": "2022-02-03"}, {"d": 1686058051}], {}),
|
45
|
+
("limit_down different format", [{"d": "2022-02-03"}, {"d": "2022-02-03T12:34:56.000000Z"}], {}),
|
46
|
+
("no scope expand", [{}, {"d": "2022-02-03"}], {}),
|
47
|
+
],
|
48
|
+
)
|
49
|
+
def test_schema_inferrer(test_name, input_records: List, expected_candidate_fields: Dict[str, str]):
|
50
|
+
inferrer = DatetimeFormatInferrer()
|
51
|
+
for record in input_records:
|
52
|
+
inferrer.accumulate(AirbyteRecordMessage(stream="abc", data=record, emitted_at=NOW))
|
53
|
+
assert inferrer.get_inferred_datetime_formats() == expected_candidate_fields
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/connector_builder/connector_builder_handler.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/checks/__init__.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/checks/check_stream.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/datetime/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/declarative_source.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/declarative_stream.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/decoders/__init__.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/decoders/decoder.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/decoders/json_decoder.py
RENAMED
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/extractors/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/incremental/__init__.py
RENAMED
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/__init__.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/filters.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/jinja.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/interpolation/macros.py
RENAMED
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/models/__init__.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/parsers/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/request_path.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/requesters/requester.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/retrievers/__init__.py
RENAMED
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/retrievers/retriever.py
RENAMED
File without changes
|
File without changes
|
{airbyte-cdk-0.40.1 → airbyte-cdk-0.40.3}/airbyte_cdk/sources/declarative/schema/__init__.py
RENAMED
File without changes
|