airbyte-cdk 0.40.3__tar.gz → 0.40.4__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (281) hide show
  1. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/PKG-INFO +1 -1
  2. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/config_observation.py +10 -2
  3. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/connector_builder/message_grouper.py +1 -1
  4. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/entrypoint.py +34 -19
  5. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/abstract_source.py +13 -0
  6. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/declarative_component_schema.yaml +61 -3
  7. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/manifest_declarative_source.py +6 -0
  8. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/models/declarative_component_schema.py +4 -4
  9. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +7 -2
  10. airbyte-cdk-0.40.4/airbyte_cdk/sources/message/__init__.py +7 -0
  11. airbyte-cdk-0.40.4/airbyte_cdk/sources/message/repository.py +36 -0
  12. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +6 -1
  13. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +9 -2
  14. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk.egg-info/PKG-INFO +1 -1
  15. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk.egg-info/SOURCES.txt +4 -0
  16. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/setup.py +1 -1
  17. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/connector_builder/test_connector_builder_handler.py +34 -3
  18. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/connector_builder/test_message_grouper.py +0 -12
  19. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/auth/test_oauth.py +3 -3
  20. airbyte-cdk-0.40.4/unit_tests/sources/message/test_repository.py +65 -0
  21. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py +30 -4
  22. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/test_abstract_source.py +47 -1
  23. airbyte-cdk-0.40.4/unit_tests/utils/__init__.py +0 -0
  24. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/LICENSE.txt +0 -0
  25. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/README.md +0 -0
  26. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/__init__.py +0 -0
  27. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/connector.py +0 -0
  28. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/connector_builder/__init__.py +0 -0
  29. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/connector_builder/connector_builder_handler.py +0 -0
  30. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/connector_builder/main.py +0 -0
  31. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/connector_builder/models.py +0 -0
  32. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/destinations/__init__.py +0 -0
  33. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/destinations/destination.py +0 -0
  34. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/exception_handler.py +0 -0
  35. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/logger.py +0 -0
  36. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/models/__init__.py +0 -0
  37. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/models/airbyte_protocol.py +0 -0
  38. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/models/well_known_types.py +0 -0
  39. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/py.typed +0 -0
  40. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/__init__.py +0 -0
  41. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/config.py +0 -0
  42. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/connector_state_manager.py +0 -0
  43. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/__init__.py +0 -0
  44. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/auth/__init__.py +0 -0
  45. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/auth/declarative_authenticator.py +0 -0
  46. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/auth/oauth.py +0 -0
  47. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/auth/token.py +0 -0
  48. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/checks/__init__.py +0 -0
  49. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/checks/check_stream.py +0 -0
  50. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/checks/connection_checker.py +0 -0
  51. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/create_partial.py +0 -0
  52. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/datetime/__init__.py +0 -0
  53. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/datetime/datetime_parser.py +0 -0
  54. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +0 -0
  55. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/declarative_source.py +0 -0
  56. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/declarative_stream.py +0 -0
  57. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/decoders/__init__.py +0 -0
  58. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/decoders/decoder.py +0 -0
  59. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/decoders/json_decoder.py +0 -0
  60. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/exceptions.py +0 -0
  61. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/extractors/__init__.py +0 -0
  62. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/extractors/dpath_extractor.py +0 -0
  63. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/extractors/http_selector.py +0 -0
  64. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/extractors/record_extractor.py +0 -0
  65. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/extractors/record_filter.py +0 -0
  66. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/extractors/record_selector.py +0 -0
  67. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/incremental/__init__.py +0 -0
  68. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +0 -0
  69. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/__init__.py +0 -0
  70. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/filters.py +0 -0
  71. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py +0 -0
  72. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py +0 -0
  73. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py +0 -0
  74. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/interpolated_string.py +0 -0
  75. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/interpolation.py +0 -0
  76. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/jinja.py +0 -0
  77. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/interpolation/macros.py +0 -0
  78. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/models/__init__.py +0 -0
  79. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/parsers/__init__.py +0 -0
  80. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/parsers/class_types_registry.py +0 -0
  81. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/parsers/custom_exceptions.py +0 -0
  82. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/parsers/default_implementation_registry.py +0 -0
  83. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +0 -0
  84. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py +0 -0
  85. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/partition_routers/__init__.py +0 -0
  86. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py +0 -0
  87. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py +0 -0
  88. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py +0 -0
  89. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/__init__.py +0 -0
  90. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py +0 -0
  91. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +0 -0
  92. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py +0 -0
  93. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py +0 -0
  94. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py +0 -0
  95. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py +0 -0
  96. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py +0 -0
  97. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py +0 -0
  98. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py +0 -0
  99. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py +0 -0
  100. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py +0 -0
  101. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py +0 -0
  102. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/response_action.py +0 -0
  103. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/error_handlers/response_status.py +0 -0
  104. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/http_requester.py +0 -0
  105. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/__init__.py +0 -0
  106. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +0 -0
  107. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py +0 -0
  108. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/paginator.py +0 -0
  109. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py +0 -0
  110. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py +0 -0
  111. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py +0 -0
  112. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py +0 -0
  113. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py +0 -0
  114. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/request_option.py +0 -0
  115. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/request_options/__init__.py +0 -0
  116. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py +0 -0
  117. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py +0 -0
  118. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py +0 -0
  119. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +0 -0
  120. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/request_path.py +0 -0
  121. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/requesters/requester.py +0 -0
  122. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/retrievers/__init__.py +0 -0
  123. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/retrievers/retriever.py +0 -0
  124. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +0 -0
  125. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/schema/__init__.py +0 -0
  126. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/schema/default_schema_loader.py +0 -0
  127. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/schema/inline_schema_loader.py +0 -0
  128. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py +0 -0
  129. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/schema/schema_loader.py +0 -0
  130. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/spec/__init__.py +0 -0
  131. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/spec/spec.py +0 -0
  132. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/stream_slicers/__init__.py +0 -0
  133. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/stream_slicers/cartesian_product_stream_slicer.py +0 -0
  134. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py +0 -0
  135. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/transformations/__init__.py +0 -0
  136. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/transformations/add_fields.py +0 -0
  137. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/transformations/remove_fields.py +0 -0
  138. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/transformations/transformation.py +0 -0
  139. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/types.py +0 -0
  140. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/declarative/yaml_declarative_source.py +0 -0
  141. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/deprecated/__init__.py +0 -0
  142. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/deprecated/base_source.py +0 -0
  143. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/deprecated/client.py +0 -0
  144. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/singer/__init__.py +0 -0
  145. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/singer/singer_helpers.py +0 -0
  146. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/singer/source.py +0 -0
  147. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/source.py +0 -0
  148. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/__init__.py +0 -0
  149. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/availability_strategy.py +0 -0
  150. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/core.py +0 -0
  151. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/__init__.py +0 -0
  152. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/auth/__init__.py +0 -0
  153. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/auth/core.py +0 -0
  154. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/auth/oauth.py +0 -0
  155. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/auth/token.py +0 -0
  156. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/availability_strategy.py +0 -0
  157. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/exceptions.py +0 -0
  158. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/http.py +0 -0
  159. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/rate_limiting.py +0 -0
  160. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py +0 -0
  161. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py +0 -0
  162. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/http/requests_native_auth/token.py +0 -0
  163. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/utils/__init__.py +0 -0
  164. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/streams/utils/stream_helper.py +0 -0
  165. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/utils/__init__.py +0 -0
  166. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/utils/casing.py +0 -0
  167. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/utils/catalog_helpers.py +0 -0
  168. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/utils/record_helper.py +0 -0
  169. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/utils/schema_helpers.py +0 -0
  170. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/utils/schema_models.py +0 -0
  171. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/sources/utils/transform.py +0 -0
  172. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/utils/__init__.py +0 -0
  173. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/utils/airbyte_secrets_utils.py +0 -0
  174. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/utils/datetime_format_inferrer.py +0 -0
  175. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/utils/event_timing.py +0 -0
  176. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/utils/schema_inferrer.py +0 -0
  177. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/utils/stream_status_utils.py +0 -0
  178. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk/utils/traced_exception.py +0 -0
  179. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk.egg-info/dependency_links.txt +0 -0
  180. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk.egg-info/requires.txt +0 -0
  181. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/airbyte_cdk.egg-info/top_level.txt +0 -0
  182. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/pyproject.toml +0 -0
  183. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/setup.cfg +0 -0
  184. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/source_declarative_manifest/__init__.py +0 -0
  185. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/source_declarative_manifest/main.py +0 -0
  186. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/connector_builder/__init__.py +0 -0
  187. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/connector_builder/utils.py +0 -0
  188. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/destinations/__init__.py +0 -0
  189. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/destinations/test_destination.py +0 -0
  190. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/singer/__init__.py +0 -0
  191. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/singer/test_singer_helpers.py +0 -0
  192. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/singer/test_singer_source.py +0 -0
  193. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/__init__.py +0 -0
  194. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/__init__.py +0 -0
  195. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/auth/__init__.py +0 -0
  196. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/auth/test_session_token_auth.py +0 -0
  197. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/auth/test_token_auth.py +0 -0
  198. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/checks/__init__.py +0 -0
  199. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/checks/test_check_stream.py +0 -0
  200. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/decoders/__init__.py +0 -0
  201. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/decoders/test_json_decoder.py +0 -0
  202. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/external_component.py +0 -0
  203. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/extractors/__init__.py +0 -0
  204. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/extractors/test_dpath_extractor.py +0 -0
  205. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/extractors/test_record_filter.py +0 -0
  206. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/extractors/test_record_selector.py +0 -0
  207. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/incremental/__init__.py +0 -0
  208. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/incremental/test_datetime_based_cursor.py +0 -0
  209. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/interpolation/__init__.py +0 -0
  210. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/interpolation/test_filters.py +0 -0
  211. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/interpolation/test_interpolated_boolean.py +0 -0
  212. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/interpolation/test_interpolated_mapping.py +0 -0
  213. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/interpolation/test_interpolated_nested_mapping.py +0 -0
  214. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/interpolation/test_interpolated_string.py +0 -0
  215. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/interpolation/test_jinja.py +0 -0
  216. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/interpolation/test_macros.py +0 -0
  217. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/parsers/__init__.py +0 -0
  218. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/parsers/test_manifest_component_transformer.py +0 -0
  219. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/parsers/test_manifest_reference_resolver.py +0 -0
  220. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py +0 -0
  221. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/parsers/testing_components.py +0 -0
  222. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/partition_routers/__init__.py +0 -0
  223. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/partition_routers/test_list_partition_router.py +0 -0
  224. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/partition_routers/test_single_partition_router.py +0 -0
  225. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/partition_routers/test_substream_partition_router.py +0 -0
  226. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/__init__.py +0 -0
  227. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/__init__.py +0 -0
  228. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +0 -0
  229. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_constant_backoff.py +0 -0
  230. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_exponential_backoff.py +0 -0
  231. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_header_helper.py +0 -0
  232. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_time_from_header.py +0 -0
  233. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_until_time_from_header.py +0 -0
  234. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/test_composite_error_handler.py +0 -0
  235. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/test_default_error_handler.py +0 -0
  236. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/test_http_response_filter.py +0 -0
  237. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/error_handlers/test_response_status.py +0 -0
  238. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/paginators/__init__.py +0 -0
  239. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/paginators/test_cursor_pagination_strategy.py +0 -0
  240. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py +0 -0
  241. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/paginators/test_no_paginator.py +0 -0
  242. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py +0 -0
  243. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/paginators/test_page_increment.py +0 -0
  244. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/paginators/test_request_option.py +0 -0
  245. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/request_options/__init__.py +0 -0
  246. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/request_options/test_interpolated_request_options_provider.py +0 -0
  247. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/test_http_requester.py +0 -0
  248. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/requesters/test_interpolated_request_input_provider.py +0 -0
  249. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/retrievers/__init__.py +0 -0
  250. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/retrievers/test_simple_retriever.py +0 -0
  251. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/schema/__init__.py +0 -0
  252. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/schema/source_test/SourceTest.py +0 -0
  253. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/schema/source_test/__init__.py +0 -0
  254. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/schema/test_default_schema_loader.py +0 -0
  255. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/schema/test_inline_schema_loader.py +0 -0
  256. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/schema/test_json_file_schema_loader.py +0 -0
  257. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/states/__init__.py +0 -0
  258. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/stream_slicers/__init__.py +0 -0
  259. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/stream_slicers/test_cartesian_product_stream_slicer.py +0 -0
  260. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/test_create_partial.py +0 -0
  261. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/test_declarative_stream.py +0 -0
  262. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/test_manifest_declarative_source.py +0 -0
  263. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/declarative/test_yaml_declarative_source.py +0 -0
  264. {airbyte-cdk-0.40.3/unit_tests/sources/streams → airbyte-cdk-0.40.4/unit_tests/sources/message}/__init__.py +0 -0
  265. {airbyte-cdk-0.40.3/unit_tests/sources/streams/http → airbyte-cdk-0.40.4/unit_tests/sources/streams}/__init__.py +0 -0
  266. {airbyte-cdk-0.40.3/unit_tests/sources/streams/http/auth → airbyte-cdk-0.40.4/unit_tests/sources/streams/http}/__init__.py +0 -0
  267. {airbyte-cdk-0.40.3/unit_tests/sources/streams/http/requests_native_auth → airbyte-cdk-0.40.4/unit_tests/sources/streams/http/auth}/__init__.py +0 -0
  268. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/streams/http/auth/test_auth.py +0 -0
  269. {airbyte-cdk-0.40.3/unit_tests/utils → airbyte-cdk-0.40.4/unit_tests/sources/streams/http/requests_native_auth}/__init__.py +0 -0
  270. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/streams/http/test_availability_strategy.py +0 -0
  271. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/streams/http/test_http.py +0 -0
  272. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/streams/test_availability_strategy.py +0 -0
  273. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/streams/test_streams_core.py +0 -0
  274. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/test_config.py +0 -0
  275. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/test_connector_state_manager.py +0 -0
  276. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/sources/test_source.py +0 -0
  277. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/utils/test_datetime_format_inferrer.py +0 -0
  278. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/utils/test_schema_inferrer.py +0 -0
  279. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/utils/test_secret_utils.py +0 -0
  280. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/utils/test_stream_status_utils.py +0 -0
  281. {airbyte-cdk-0.40.3 → airbyte-cdk-0.40.4}/unit_tests/utils/test_traced_exception.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-cdk
3
- Version: 0.40.3
3
+ Version: 0.40.4
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  Home-page: https://github.com/airbytehq/airbyte
6
6
  Author: Airbyte
@@ -68,10 +68,18 @@ def observe_connector_config(non_observed_connector_config: MutableMapping[str,
68
68
 
69
69
 
70
70
  def emit_configuration_as_airbyte_control_message(config: MutableMapping):
71
+ """
72
+ WARNING: deprecated - emit_configuration_as_airbyte_control_message is being deprecated in favor of the MessageRepository mechanism.
73
+ See the airbyte_cdk.sources.message package
74
+ """
75
+ airbyte_message = create_connector_config_control_message(config)
76
+ print(airbyte_message.json(exclude_unset=True))
77
+
78
+
79
+ def create_connector_config_control_message(config):
71
80
  control_message = AirbyteControlMessage(
72
81
  type=OrchestratorType.CONNECTOR_CONFIG,
73
82
  emitted_at=time.time() * 1000,
74
83
  connectorConfig=AirbyteControlConnectorConfigMessage(config=config),
75
84
  )
76
- airbyte_message = AirbyteMessage(type=Type.CONTROL, control=control_message)
77
- print(airbyte_message.json(exclude_unset=True))
85
+ return AirbyteMessage(type=Type.CONTROL, control=control_message)
@@ -82,7 +82,7 @@ class MessageGrouper:
82
82
  inferred_schema=schema_inferrer.get_stream_schema(
83
83
  configured_catalog.streams[0].stream.name
84
84
  ), # The connector builder currently only supports reading from a single stream at a time
85
- latest_config_update=latest_config_update.connectorConfig.config if latest_config_update else self._clean_config(config),
85
+ latest_config_update=self._clean_config(latest_config_update.connectorConfig.config) if latest_config_update else None,
86
86
  inferred_datetime_formats=datetime_format_inferrer.get_inferred_datetime_formats(),
87
87
  )
88
88
 
@@ -77,27 +77,32 @@ class AirbyteEntrypoint(object):
77
77
  else:
78
78
  self.logger.setLevel(logging.INFO)
79
79
 
80
- # todo: add try catch for exceptions with different exit codes
81
80
  source_spec: ConnectorSpecification = self.source.spec(self.logger)
82
- with tempfile.TemporaryDirectory() as temp_dir:
83
- if cmd == "spec":
84
- message = AirbyteMessage(type=Type.SPEC, spec=source_spec)
85
- yield message.json(exclude_unset=True)
86
- else:
87
- raw_config = self.source.read_config(parsed_args.config)
88
- config = self.source.configure(raw_config, temp_dir)
89
-
90
- if cmd == "check":
91
- yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.check(source_spec, config))
92
- elif cmd == "discover":
93
- yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.discover(source_spec, config))
94
- elif cmd == "read":
95
- config_catalog = self.source.read_catalog(parsed_args.catalog)
96
- state = self.source.read_state(parsed_args.state)
97
-
98
- yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.read(source_spec, config, config_catalog, state))
81
+ try:
82
+ with tempfile.TemporaryDirectory() as temp_dir:
83
+ if cmd == "spec":
84
+ message = AirbyteMessage(type=Type.SPEC, spec=source_spec)
85
+ yield from [
86
+ self.airbyte_message_to_string(queued_message) for queued_message in self._emit_queued_messages(self.source)
87
+ ]
88
+ yield self.airbyte_message_to_string(message)
99
89
  else:
100
- raise Exception("Unexpected command " + cmd)
90
+ raw_config = self.source.read_config(parsed_args.config)
91
+ config = self.source.configure(raw_config, temp_dir)
92
+
93
+ if cmd == "check":
94
+ yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.check(source_spec, config))
95
+ elif cmd == "discover":
96
+ yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.discover(source_spec, config))
97
+ elif cmd == "read":
98
+ config_catalog = self.source.read_catalog(parsed_args.catalog)
99
+ state = self.source.read_state(parsed_args.state)
100
+
101
+ yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.read(source_spec, config, config_catalog, state))
102
+ else:
103
+ raise Exception("Unexpected command " + cmd)
104
+ finally:
105
+ yield from [self.airbyte_message_to_string(queued_message) for queued_message in self._emit_queued_messages(self.source)]
101
106
 
102
107
  def check(self, source_spec: ConnectorSpecification, config: TConfig) -> Iterable[AirbyteMessage]:
103
108
  self.set_up_secret_filter(config, source_spec.connectionSpecification)
@@ -106,6 +111,7 @@ class AirbyteEntrypoint(object):
106
111
  except AirbyteTracedException as traced_exc:
107
112
  connection_status = traced_exc.as_connection_status_message()
108
113
  if connection_status:
114
+ yield from self._emit_queued_messages(self.source)
109
115
  yield connection_status
110
116
  return
111
117
 
@@ -115,6 +121,7 @@ class AirbyteEntrypoint(object):
115
121
  else:
116
122
  self.logger.error("Check failed")
117
123
 
124
+ yield from self._emit_queued_messages(self.source)
118
125
  yield AirbyteMessage(type=Type.CONNECTION_STATUS, connectionStatus=check_result)
119
126
 
120
127
  def discover(self, source_spec: ConnectorSpecification, config: TConfig) -> Iterable[AirbyteMessage]:
@@ -122,6 +129,8 @@ class AirbyteEntrypoint(object):
122
129
  if self.source.check_config_against_spec:
123
130
  self.validate_connection(source_spec, config)
124
131
  catalog = self.source.discover(self.logger, config)
132
+
133
+ yield from self._emit_queued_messages(self.source)
125
134
  yield AirbyteMessage(type=Type.CATALOG, catalog=catalog)
126
135
 
127
136
  def read(self, source_spec: ConnectorSpecification, config: TConfig, catalog: TCatalog, state: TState) -> Iterable[AirbyteMessage]:
@@ -130,6 +139,7 @@ class AirbyteEntrypoint(object):
130
139
  self.validate_connection(source_spec, config)
131
140
 
132
141
  yield from self.source.read(self.logger, config, catalog, state)
142
+ yield from self._emit_queued_messages(self.source)
133
143
 
134
144
  @staticmethod
135
145
  def validate_connection(source_spec: ConnectorSpecification, config: Mapping[str, Any]) -> None:
@@ -149,6 +159,11 @@ class AirbyteEntrypoint(object):
149
159
  def airbyte_message_to_string(airbyte_message: AirbyteMessage) -> str:
150
160
  return airbyte_message.json(exclude_unset=True)
151
161
 
162
+ def _emit_queued_messages(self, source) -> Iterable[AirbyteMessage]:
163
+ if hasattr(source, "message_repository") and source.message_repository:
164
+ yield from source.message_repository.consume_queue()
165
+ return
166
+
152
167
 
153
168
  def launch(source: Source, args: List[str]):
154
169
  source_entrypoint = AirbyteEntrypoint(source)
@@ -22,6 +22,7 @@ from airbyte_cdk.models import (
22
22
  )
23
23
  from airbyte_cdk.models import Type as MessageType
24
24
  from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager
25
+ from airbyte_cdk.sources.message import MessageRepository
25
26
  from airbyte_cdk.sources.source import Source
26
27
  from airbyte_cdk.sources.streams import Stream
27
28
  from airbyte_cdk.sources.streams.core import StreamData
@@ -130,6 +131,7 @@ class AbstractSource(Source, ABC):
130
131
  yield stream_status_as_airbyte_message(configured_stream, AirbyteStreamStatus.INCOMPLETE)
131
132
  raise e
132
133
  except Exception as e:
134
+ yield from self._emit_queued_messages()
133
135
  logger.exception(f"Encountered an exception while reading stream {configured_stream.stream.name}")
134
136
  logger.info(f"Marking stream {configured_stream.stream.name} as STOPPED")
135
137
  yield stream_status_as_airbyte_message(configured_stream, AirbyteStreamStatus.INCOMPLETE)
@@ -198,6 +200,7 @@ class AbstractSource(Source, ABC):
198
200
  logger.info(f"Marking stream {stream_name} as RUNNING")
199
201
  # If we just read the first record of the stream, emit the transition to the RUNNING state
200
202
  yield stream_status_as_airbyte_message(configured_stream, AirbyteStreamStatus.RUNNING)
203
+ yield from self._emit_queued_messages()
201
204
  yield record
202
205
 
203
206
  logger.info(f"Read {record_counter} records from {stream_name} stream")
@@ -264,6 +267,7 @@ class AbstractSource(Source, ABC):
264
267
  record_counter = 0
265
268
  for message_counter, record_data_or_message in enumerate(records, start=1):
266
269
  message = self._get_message(record_data_or_message, stream_instance)
270
+ yield from self._emit_queued_messages()
267
271
  yield message
268
272
  if message.type == MessageType.RECORD:
269
273
  record = message.record
@@ -298,6 +302,11 @@ class AbstractSource(Source, ABC):
298
302
  """
299
303
  return logger.isEnabledFor(logging.DEBUG)
300
304
 
305
+ def _emit_queued_messages(self):
306
+ if self.message_repository:
307
+ yield from self.message_repository.consume_queue()
308
+ return
309
+
301
310
  def _read_full_refresh(
302
311
  self,
303
312
  logger: logging.Logger,
@@ -357,3 +366,7 @@ class AbstractSource(Source, ABC):
357
366
  return record_data_or_message
358
367
  else:
359
368
  return stream_data_to_airbyte_message(stream.name, record_data_or_message, stream.transformer, stream.get_json_schema())
369
+
370
+ @property
371
+ def message_repository(self) -> Union[None, MessageRepository]:
372
+ return None
@@ -580,10 +580,40 @@ definitions:
580
580
  - "{{ config['record_cursor'] }}"
581
581
  datetime_format:
582
582
  title: Cursor Field Datetime Format
583
- description: The datetime format of the Cursor Field.
583
+ description: |
584
+ The datetime format of the Cursor Field. Use placeholders starting with "%" to describe the format the API is using. The following placeholders are available:
585
+ * **%s**: Epoch unix timestamp - `1686218963`
586
+ * **%a**: Weekday (abbreviated) - `Sun`
587
+ * **%A**: Weekday (full) - `Sunday`
588
+ * **%w**: Weekday (decimal) - `0` (Sunday), `6` (Saturday)
589
+ * **%d**: Day of the month (zero-padded) - `01`, `02`, ..., `31`
590
+ * **%b**: Month (abbreviated) - `Jan`
591
+ * **%B**: Month (full) - `January`
592
+ * **%m**: Month (zero-padded) - `01`, `02`, ..., `12`
593
+ * **%y**: Year (without century, zero-padded) - `00`, `01`, ..., `99`
594
+ * **%Y**: Year (with century) - `0001`, `0002`, ..., `9999`
595
+ * **%H**: Hour (24-hour, zero-padded) - `00`, `01`, ..., `23`
596
+ * **%I**: Hour (12-hour, zero-padded) - `01`, `02`, ..., `12`
597
+ * **%p**: AM/PM indicator
598
+ * **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`
599
+ * **%S**: Second (zero-padded) - `00`, `01`, ..., `59`
600
+ * **%f**: Microsecond (zero-padded to 6 digits) - `000000`
601
+ * **%z**: UTC offset - `(empty)`, `+0000`, `-0400`
602
+ * **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`
603
+ * **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`
604
+ * **%U**: Week number of the year (starting Sunday) - `00`, ..., `53`
605
+ * **%W**: Week number of the year (starting Monday) - `00`, ..., `53`
606
+ * **%c**: Date and time - `Tue Aug 16 21:30:00 1988`
607
+ * **%x**: Date standard format - `08/16/1988`
608
+ * **%X**: Time standard format - `21:30:00`
609
+ * **%%**: Literal '%' character
610
+
611
+ Some placeholders depend on the locale of the underlying system - in most cases this locale is configured as en/US. For more information see the [Python documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).
584
612
  type: string
585
613
  examples:
586
614
  - "%Y-%m-%dT%H:%M:%S.%f%z"
615
+ - "%Y-%m-%d"
616
+ - "%s"
587
617
  cursor_granularity:
588
618
  title: Cursor Granularity
589
619
  description:
@@ -1283,11 +1313,39 @@ definitions:
1283
1313
  - "{{ config['start_time'] }}"
1284
1314
  datetime_format:
1285
1315
  title: Datetime Format
1286
- description: Format of the datetime value. Defaults to "%Y-%m-%dT%H:%M:%S.%f%z" if left empty. Use %s if the datetime value is in epoch time (Unix timestamp).
1316
+ description: |
1317
+ Format of the datetime value. Defaults to "%Y-%m-%dT%H:%M:%S.%f%z" if left empty. Use placeholders starting with "%" to describe the format the API is using. The following placeholders are available:
1318
+ * **%s**: Epoch unix timestamp - `1686218963`
1319
+ * **%a**: Weekday (abbreviated) - `Sun`
1320
+ * **%A**: Weekday (full) - `Sunday`
1321
+ * **%w**: Weekday (decimal) - `0` (Sunday), `6` (Saturday)
1322
+ * **%d**: Day of the month (zero-padded) - `01`, `02`, ..., `31`
1323
+ * **%b**: Month (abbreviated) - `Jan`
1324
+ * **%B**: Month (full) - `January`
1325
+ * **%m**: Month (zero-padded) - `01`, `02`, ..., `12`
1326
+ * **%y**: Year (without century, zero-padded) - `00`, `01`, ..., `99`
1327
+ * **%Y**: Year (with century) - `0001`, `0002`, ..., `9999`
1328
+ * **%H**: Hour (24-hour, zero-padded) - `00`, `01`, ..., `23`
1329
+ * **%I**: Hour (12-hour, zero-padded) - `01`, `02`, ..., `12`
1330
+ * **%p**: AM/PM indicator
1331
+ * **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`
1332
+ * **%S**: Second (zero-padded) - `00`, `01`, ..., `59`
1333
+ * **%f**: Microsecond (zero-padded to 6 digits) - `000000`, `000001`, ..., `999999`
1334
+ * **%z**: UTC offset - `(empty)`, `+0000`, `-0400`, `+1030`, `+063415`, `-030712.345216`
1335
+ * **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`
1336
+ * **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`
1337
+ * **%U**: Week number of the year (Sunday as first day) - `00`, `01`, ..., `53`
1338
+ * **%W**: Week number of the year (Monday as first day) - `00`, `01`, ..., `53`
1339
+ * **%c**: Date and time representation - `Tue Aug 16 21:30:00 1988`
1340
+ * **%x**: Date representation - `08/16/1988`
1341
+ * **%X**: Time representation - `21:30:00`
1342
+ * **%%**: Literal '%' character
1343
+
1344
+ Some placeholders depend on the locale of the underlying system - in most cases this locale is configured as en/US. For more information see the [Python documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).
1287
1345
  type: string
1288
1346
  default: ""
1289
1347
  examples:
1290
- - "%Y-%m-%dT%H:%M:%S.%f%"
1348
+ - "%Y-%m-%dT%H:%M:%S.%f%z"
1291
1349
  - "%Y-%m-%d"
1292
1350
  - "%s"
1293
1351
  max_datetime:
@@ -26,6 +26,7 @@ from airbyte_cdk.sources.declarative.parsers.manifest_component_transformer impo
26
26
  from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ManifestReferenceResolver
27
27
  from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory
28
28
  from airbyte_cdk.sources.declarative.types import ConnectionDefinition
29
+ from airbyte_cdk.sources.message import MessageRepository
29
30
  from airbyte_cdk.sources.streams.core import Stream
30
31
  from jsonschema.exceptions import ValidationError
31
32
  from jsonschema.validators import validate
@@ -61,6 +62,7 @@ class ManifestDeclarativeSource(DeclarativeSource):
61
62
  self._debug = debug
62
63
  self._emit_connector_builder_messages = emit_connector_builder_messages
63
64
  self._constructor = component_factory if component_factory else ModelToComponentFactory(emit_connector_builder_messages)
65
+ self._message_repository = self._constructor.get_message_repository()
64
66
 
65
67
  self._validate_source()
66
68
 
@@ -68,6 +70,10 @@ class ManifestDeclarativeSource(DeclarativeSource):
68
70
  def resolved_manifest(self) -> Mapping[str, Any]:
69
71
  return self._source_config
70
72
 
73
+ @property
74
+ def message_repository(self) -> Union[None, MessageRepository]:
75
+ return self._message_repository
76
+
71
77
  @property
72
78
  def connection_checker(self) -> ConnectionChecker:
73
79
  check = self._source_config["check"]
@@ -453,8 +453,8 @@ class MinMaxDatetime(BaseModel):
453
453
  )
454
454
  datetime_format: Optional[str] = Field(
455
455
  "",
456
- description='Format of the datetime value. Defaults to "%Y-%m-%dT%H:%M:%S.%f%z" if left empty. Use %s if the datetime value is in epoch time (Unix timestamp).',
457
- examples=["%Y-%m-%dT%H:%M:%S.%f%", "%Y-%m-%d", "%s"],
456
+ description='Format of the datetime value. Defaults to "%Y-%m-%dT%H:%M:%S.%f%z" if left empty. Use placeholders starting with "%" to describe the format the API is using. The following placeholders are available:\n * **%s**: Epoch unix timestamp - `1686218963`\n * **%a**: Weekday (abbreviated) - `Sun`\n * **%A**: Weekday (full) - `Sunday`\n * **%w**: Weekday (decimal) - `0` (Sunday), `6` (Saturday)\n * **%d**: Day of the month (zero-padded) - `01`, `02`, ..., `31`\n * **%b**: Month (abbreviated) - `Jan`\n * **%B**: Month (full) - `January`\n * **%m**: Month (zero-padded) - `01`, `02`, ..., `12`\n * **%y**: Year (without century, zero-padded) - `00`, `01`, ..., `99`\n * **%Y**: Year (with century) - `0001`, `0002`, ..., `9999`\n * **%H**: Hour (24-hour, zero-padded) - `00`, `01`, ..., `23`\n * **%I**: Hour (12-hour, zero-padded) - `01`, `02`, ..., `12`\n * **%p**: AM/PM indicator\n * **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`\n * **%S**: Second (zero-padded) - `00`, `01`, ..., `59`\n * **%f**: Microsecond (zero-padded to 6 digits) - `000000`, `000001`, ..., `999999`\n * **%z**: UTC offset - `(empty)`, `+0000`, `-0400`, `+1030`, `+063415`, `-030712.345216`\n * **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`\n * **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`\n * **%U**: Week number of the year (Sunday as first day) - `00`, `01`, ..., `53`\n * **%W**: Week number of the year (Monday as first day) - `00`, `01`, ..., `53`\n * **%c**: Date and time representation - `Tue Aug 16 21:30:00 1988`\n * **%x**: Date representation - `08/16/1988`\n * **%X**: Time representation - `21:30:00`\n * **%%**: Literal \'%\' character\n\n Some placeholders depend on the locale of the underlying system - in most cases this locale is configured as en/US. For more information see the [Python documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).\n',
457
+ examples=["%Y-%m-%dT%H:%M:%S.%f%z", "%Y-%m-%d", "%s"],
458
458
  title="Datetime Format",
459
459
  )
460
460
  max_datetime: Optional[str] = Field(
@@ -806,8 +806,8 @@ class DatetimeBasedCursor(BaseModel):
806
806
  )
807
807
  datetime_format: str = Field(
808
808
  ...,
809
- description="The datetime format of the Cursor Field.",
810
- examples=["%Y-%m-%dT%H:%M:%S.%f%z"],
809
+ description="The datetime format of the Cursor Field. Use placeholders starting with \"%\" to describe the format the API is using. The following placeholders are available:\n * **%s**: Epoch unix timestamp - `1686218963`\n * **%a**: Weekday (abbreviated) - `Sun`\n * **%A**: Weekday (full) - `Sunday`\n * **%w**: Weekday (decimal) - `0` (Sunday), `6` (Saturday)\n * **%d**: Day of the month (zero-padded) - `01`, `02`, ..., `31`\n * **%b**: Month (abbreviated) - `Jan`\n * **%B**: Month (full) - `January`\n * **%m**: Month (zero-padded) - `01`, `02`, ..., `12`\n * **%y**: Year (without century, zero-padded) - `00`, `01`, ..., `99`\n * **%Y**: Year (with century) - `0001`, `0002`, ..., `9999`\n * **%H**: Hour (24-hour, zero-padded) - `00`, `01`, ..., `23`\n * **%I**: Hour (12-hour, zero-padded) - `01`, `02`, ..., `12`\n * **%p**: AM/PM indicator\n * **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`\n * **%S**: Second (zero-padded) - `00`, `01`, ..., `59`\n * **%f**: Microsecond (zero-padded to 6 digits) - `000000`\n * **%z**: UTC offset - `(empty)`, `+0000`, `-0400`\n * **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`\n * **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`\n * **%U**: Week number of the year (starting Sunday) - `00`, ..., `53`\n * **%W**: Week number of the year (starting Monday) - `00`, ..., `53`\n * **%c**: Date and time - `Tue Aug 16 21:30:00 1988`\n * **%x**: Date standard format - `08/16/1988`\n * **%X**: Time standard format - `21:30:00`\n * **%%**: Literal '%' character\n\n Some placeholders depend on the locale of the underlying system - in most cases this locale is configured as en/US. For more information see the [Python documentation](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes).\n",
810
+ examples=["%Y-%m-%dT%H:%M:%S.%f%z", "%Y-%m-%d", "%s"],
811
811
  title="Cursor Field Datetime Format",
812
812
  )
813
813
  cursor_granularity: Optional[str] = Field(
@@ -100,6 +100,7 @@ from airbyte_cdk.sources.declarative.stream_slicers import CartesianProductStrea
100
100
  from airbyte_cdk.sources.declarative.transformations import AddFields, RemoveFields
101
101
  from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition
102
102
  from airbyte_cdk.sources.declarative.types import Config
103
+ from airbyte_cdk.sources.message import InMemoryMessageRepository
103
104
  from pydantic import BaseModel
104
105
 
105
106
  ComponentDefinition: Union[Literal, Mapping, List]
@@ -121,6 +122,7 @@ class ModelToComponentFactory:
121
122
  self._limit_slices_fetched = limit_slices_fetched
122
123
  self._emit_connector_builder_messages = emit_connector_builder_messages
123
124
  self._disable_retries = disable_retries
125
+ self._message_repository = InMemoryMessageRepository()
124
126
 
125
127
  def _init_mappings(self):
126
128
  self.PYDANTIC_MODEL_TO_CONSTRUCTOR: [Type[BaseModel], Callable] = {
@@ -675,8 +677,7 @@ class ModelToComponentFactory:
675
677
  def create_no_pagination(model: NoPaginationModel, config: Config, **kwargs) -> NoPagination:
676
678
  return NoPagination(parameters={})
677
679
 
678
- @staticmethod
679
- def create_oauth_authenticator(model: OAuthAuthenticatorModel, config: Config, **kwargs) -> DeclarativeOauth2Authenticator:
680
+ def create_oauth_authenticator(self, model: OAuthAuthenticatorModel, config: Config, **kwargs) -> DeclarativeOauth2Authenticator:
680
681
  if model.refresh_token_updater:
681
682
  return DeclarativeSingleUseRefreshTokenOauth2Authenticator(
682
683
  config,
@@ -693,6 +694,7 @@ class ModelToComponentFactory:
693
694
  refresh_request_body=InterpolatedMapping(model.refresh_request_body or {}, parameters=model.parameters).eval(config),
694
695
  scopes=model.scopes,
695
696
  token_expiry_date_format=model.token_expiry_date_format,
697
+ message_repository=self._message_repository,
696
698
  )
697
699
  return DeclarativeOauth2Authenticator(
698
700
  access_token_name=model.access_token_name,
@@ -845,3 +847,6 @@ class ModelToComponentFactory:
845
847
  return WaitUntilTimeFromHeaderBackoffStrategy(
846
848
  header=model.header, parameters=model.parameters, config=config, min_wait=model.min_wait, regex=model.regex
847
849
  )
850
+
851
+ def get_message_repository(self):
852
+ return self._message_repository
@@ -0,0 +1,7 @@
1
+ #
2
+ # Copyright (c) 2021 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from .repository import InMemoryMessageRepository, MessageRepository
6
+
7
+ __all__ = ["InMemoryMessageRepository", "MessageRepository"]
@@ -0,0 +1,36 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from abc import ABC, abstractmethod
6
+ from typing import Iterable
7
+
8
+ from airbyte_cdk.models import AirbyteMessage, Type
9
+
10
+
11
+ class MessageRepository(ABC):
12
+ @abstractmethod
13
+ def emit_message(self, message: AirbyteMessage) -> None:
14
+ raise NotImplementedError()
15
+
16
+ @abstractmethod
17
+ def consume_queue(self) -> Iterable[AirbyteMessage]:
18
+ raise NotImplementedError()
19
+
20
+
21
+ class InMemoryMessageRepository(MessageRepository):
22
+ def __init__(self):
23
+ self._message_queue = []
24
+
25
+ def emit_message(self, message: AirbyteMessage) -> None:
26
+ """
27
+ :param message: As of today, only AirbyteControlMessages are supported given that supporting other types of message will need more
28
+ work and therefore this work has been postponed
29
+ """
30
+ if message.type != Type.CONTROL:
31
+ raise ValueError("As of today, only AirbyteControlMessages are supported as part of the InMemoryMessageRepository")
32
+ self._message_queue.append(message)
33
+
34
+ def consume_queue(self) -> Iterable[AirbyteMessage]:
35
+ while self._message_queue:
36
+ yield self._message_queue.pop(0)
@@ -79,7 +79,12 @@ class AbstractOauth2Authenticator(AuthBase):
79
79
  )
80
80
  def _get_refresh_access_token_response(self):
81
81
  try:
82
- response = requests.request(method="POST", url=self.get_token_refresh_endpoint(), data=self.build_refresh_request_body())
82
+ response = requests.request(
83
+ method="POST",
84
+ url=self.get_token_refresh_endpoint(),
85
+ data=self.build_refresh_request_body(),
86
+ headers={"Content-Type": "application/json"},
87
+ )
83
88
  response.raise_for_status()
84
89
  return response.json()
85
90
  except requests.exceptions.RequestException as e:
@@ -6,7 +6,8 @@ from typing import Any, List, Mapping, Optional, Sequence, Tuple, Union
6
6
 
7
7
  import dpath
8
8
  import pendulum
9
- from airbyte_cdk.config_observation import emit_configuration_as_airbyte_control_message
9
+ from airbyte_cdk.config_observation import create_connector_config_control_message, emit_configuration_as_airbyte_control_message
10
+ from airbyte_cdk.sources.message import MessageRepository
10
11
  from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth import AbstractOauth2Authenticator
11
12
 
12
13
 
@@ -115,6 +116,7 @@ class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator):
115
116
  refresh_token_config_path: Sequence[str] = ("credentials", "refresh_token"),
116
117
  token_expiry_date_config_path: Sequence[str] = ("credentials", "token_expiry_date"),
117
118
  token_expiry_date_format: Optional[str] = None,
119
+ message_repository: MessageRepository = None,
118
120
  ):
119
121
  """
120
122
 
@@ -144,6 +146,7 @@ class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator):
144
146
  self._token_expiry_date_format = token_expiry_date_format
145
147
  self._refresh_token_name = refresh_token_name
146
148
  self._connector_config = connector_config
149
+ self._message_repository = message_repository
147
150
  super().__init__(
148
151
  token_refresh_endpoint,
149
152
  self.get_client_id(),
@@ -211,7 +214,11 @@ class SingleUseRefreshTokenOauth2Authenticator(Oauth2Authenticator):
211
214
  self.access_token = new_access_token
212
215
  self.set_refresh_token(new_refresh_token)
213
216
  self.set_token_expiry_date(new_token_expiry_date)
214
- emit_configuration_as_airbyte_control_message(self._connector_config)
217
+ if self._message_repository:
218
+ self._message_repository.emit_message(create_connector_config_control_message(self._connector_config))
219
+ else:
220
+ # FIXME emit_configuration_as_airbyte_control_message as been deprecated in favor of package airbyte_cdk.sources.message
221
+ emit_configuration_as_airbyte_control_message(self._connector_config)
215
222
  return self.access_token
216
223
 
217
224
  def refresh_access_token(self) -> Tuple[str, str, str]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-cdk
3
- Version: 0.40.3
3
+ Version: 0.40.4
4
4
  Summary: A framework for writing Airbyte Connectors.
5
5
  Home-page: https://github.com/airbytehq/airbyte
6
6
  Author: Airbyte
@@ -134,6 +134,8 @@ airbyte_cdk/sources/declarative/transformations/transformation.py
134
134
  airbyte_cdk/sources/deprecated/__init__.py
135
135
  airbyte_cdk/sources/deprecated/base_source.py
136
136
  airbyte_cdk/sources/deprecated/client.py
137
+ airbyte_cdk/sources/message/__init__.py
138
+ airbyte_cdk/sources/message/repository.py
137
139
  airbyte_cdk/sources/singer/__init__.py
138
140
  airbyte_cdk/sources/singer/singer_helpers.py
139
141
  airbyte_cdk/sources/singer/source.py
@@ -257,6 +259,8 @@ unit_tests/sources/declarative/schema/source_test/__init__.py
257
259
  unit_tests/sources/declarative/states/__init__.py
258
260
  unit_tests/sources/declarative/stream_slicers/__init__.py
259
261
  unit_tests/sources/declarative/stream_slicers/test_cartesian_product_stream_slicer.py
262
+ unit_tests/sources/message/__init__.py
263
+ unit_tests/sources/message/test_repository.py
260
264
  unit_tests/sources/streams/__init__.py
261
265
  unit_tests/sources/streams/test_availability_strategy.py
262
266
  unit_tests/sources/streams/test_streams_core.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.3",
20
+ version="0.40.4",
21
21
  description="A framework for writing Airbyte Connectors.",
22
22
  long_description=README,
23
23
  long_description_content_type="text/markdown",
@@ -176,9 +176,9 @@ def invalid_config_file(tmp_path):
176
176
 
177
177
 
178
178
  def test_handle_resolve_manifest(valid_resolve_manifest_config_file, dummy_catalog):
179
- with mock.patch.object(connector_builder.main, "handle_connector_builder_request") as patch:
179
+ with mock.patch.object(connector_builder.main, "handle_connector_builder_request") as patched_handle:
180
180
  handle_request(["read", "--config", str(valid_resolve_manifest_config_file), "--catalog", str(dummy_catalog)])
181
- assert patch.call_count == 1
181
+ assert patched_handle.call_count == 1
182
182
 
183
183
 
184
184
  def test_handle_test_read(valid_read_config_file, configured_catalog):
@@ -384,6 +384,37 @@ def test_read():
384
384
  assert output_record == expected_airbyte_message
385
385
 
386
386
 
387
+ def test_config_update():
388
+ manifest = copy.deepcopy(MANIFEST)
389
+ manifest["definitions"]["retriever"]["requester"]["authenticator"] = {
390
+ "type": "OAuthAuthenticator",
391
+ "token_refresh_endpoint": "https://oauth.endpoint.com/tokens/bearer",
392
+ "client_id": "{{ config['credentials']['client_id'] }}",
393
+ "client_secret": "{{ config['credentials']['client_secret'] }}",
394
+ "refresh_token": "{{ config['credentials']['refresh_token'] }}",
395
+ "refresh_token_updater": {}
396
+ }
397
+ config = copy.deepcopy(TEST_READ_CONFIG)
398
+ config["__injected_declarative_manifest"] = manifest
399
+ config["credentials"] = {
400
+ "client_id": "a client id",
401
+ "client_secret": "a client secret",
402
+ "refresh_token": "a refresh token",
403
+ }
404
+ source = ManifestDeclarativeSource(manifest)
405
+
406
+ refresh_request_response = {
407
+ "access_token": "an updated access token",
408
+ "refresh_token": "an updated refresh token",
409
+ "expires_in": 3600,
410
+ }
411
+ with patch("airbyte_cdk.sources.streams.http.requests_native_auth.SingleUseRefreshTokenOauth2Authenticator._get_refresh_access_token_response", return_value=refresh_request_response):
412
+ output = handle_connector_builder_request(
413
+ source, "test_read", config, ConfiguredAirbyteCatalog.parse_obj(CONFIGURED_CATALOG), TestReadLimits()
414
+ )
415
+ assert output.record.data["latest_config_update"]
416
+
417
+
387
418
  @patch("traceback.TracebackException.from_exception")
388
419
  def test_read_returns_error_response(mock_from_exception):
389
420
  class MockManifestDeclarativeSource:
@@ -413,7 +444,7 @@ def test_read_returns_error_response(mock_from_exception):
413
444
  test_read_limit_reached=False,
414
445
  inferred_schema=None,
415
446
  inferred_datetime_formats={},
416
- latest_config_update={})
447
+ latest_config_update=None)
417
448
 
418
449
  expected_message = AirbyteMessage(
419
450
  type=MessageType.RECORD,
@@ -554,18 +554,6 @@ def test_given_control_message_then_stream_read_has_config_update(mock_entrypoin
554
554
  assert stream_read.latest_config_update == updated_config
555
555
 
556
556
 
557
- @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read')
558
- def test_given_no_control_message_then_use_in_memory_config_change_as_update(mock_entrypoint_read):
559
- mock_source = make_mock_source(mock_entrypoint_read, iter(any_request_and_response_with_a_record()))
560
- connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES)
561
- full_config = {**CONFIG, **{"__injected_declarative_manifest": MANIFEST}}
562
- stream_read: StreamRead = connector_builder_handler.get_message_groups(
563
- source=mock_source, config=full_config, configured_catalog=create_configured_catalog("hashiras")
564
- )
565
-
566
- assert stream_read.latest_config_update == CONFIG
567
-
568
-
569
557
  @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read')
570
558
  def test_given_multiple_control_messages_then_stream_read_has_latest_based_on_emitted_at(mock_entrypoint_read):
571
559
  earliest = 0
@@ -203,7 +203,7 @@ class TestOauth2Authenticator:
203
203
  assert oauth.get_token_expiry_date() == pendulum.parse(next_day)
204
204
 
205
205
 
206
- def mock_request(method, url, data):
207
- if url == "refresh_end":
206
+ def mock_request(method, url, data, headers):
207
+ if url == "refresh_end" and headers == {"Content-Type": "application/json"}:
208
208
  return resp
209
- raise Exception(f"Error while refreshing access token with request: {method}, {url}, {data}")
209
+ raise Exception(f"Error while refreshing access token with request: {method}, {url}, {data}, {headers}")