airbyte-cdk 0.72.1__py3-none-any.whl → 6.13.1.dev4106__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (517) hide show
  1. airbyte_cdk/__init__.py +355 -6
  2. airbyte_cdk/cli/__init__.py +1 -0
  3. airbyte_cdk/cli/source_declarative_manifest/__init__.py +5 -0
  4. airbyte_cdk/cli/source_declarative_manifest/_run.py +230 -0
  5. airbyte_cdk/cli/source_declarative_manifest/spec.json +17 -0
  6. airbyte_cdk/config_observation.py +29 -10
  7. airbyte_cdk/connector.py +24 -24
  8. airbyte_cdk/connector_builder/README.md +53 -0
  9. airbyte_cdk/connector_builder/connector_builder_handler.py +37 -11
  10. airbyte_cdk/connector_builder/main.py +45 -13
  11. airbyte_cdk/connector_builder/message_grouper.py +189 -50
  12. airbyte_cdk/connector_builder/models.py +3 -2
  13. airbyte_cdk/destinations/__init__.py +4 -3
  14. airbyte_cdk/destinations/destination.py +54 -20
  15. airbyte_cdk/destinations/vector_db_based/README.md +37 -0
  16. airbyte_cdk/destinations/vector_db_based/config.py +40 -17
  17. airbyte_cdk/destinations/vector_db_based/document_processor.py +56 -17
  18. airbyte_cdk/destinations/vector_db_based/embedder.py +57 -15
  19. airbyte_cdk/destinations/vector_db_based/test_utils.py +14 -4
  20. airbyte_cdk/destinations/vector_db_based/utils.py +8 -2
  21. airbyte_cdk/destinations/vector_db_based/writer.py +24 -5
  22. airbyte_cdk/entrypoint.py +153 -44
  23. airbyte_cdk/exception_handler.py +21 -3
  24. airbyte_cdk/logger.py +30 -44
  25. airbyte_cdk/models/__init__.py +13 -2
  26. airbyte_cdk/models/airbyte_protocol.py +86 -1
  27. airbyte_cdk/models/airbyte_protocol_serializers.py +44 -0
  28. airbyte_cdk/models/file_transfer_record_message.py +13 -0
  29. airbyte_cdk/models/well_known_types.py +1 -1
  30. airbyte_cdk/sources/__init__.py +5 -1
  31. airbyte_cdk/sources/abstract_source.py +125 -79
  32. airbyte_cdk/sources/concurrent_source/__init__.py +7 -2
  33. airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py +102 -36
  34. airbyte_cdk/sources/concurrent_source/concurrent_source.py +29 -36
  35. airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py +94 -10
  36. airbyte_cdk/sources/concurrent_source/stream_thread_exception.py +25 -0
  37. airbyte_cdk/sources/concurrent_source/thread_pool_manager.py +20 -14
  38. airbyte_cdk/sources/config.py +3 -2
  39. airbyte_cdk/sources/connector_state_manager.py +49 -83
  40. airbyte_cdk/sources/declarative/async_job/job.py +52 -0
  41. airbyte_cdk/sources/declarative/async_job/job_orchestrator.py +497 -0
  42. airbyte_cdk/sources/declarative/async_job/job_tracker.py +75 -0
  43. airbyte_cdk/sources/declarative/async_job/repository.py +35 -0
  44. airbyte_cdk/sources/declarative/async_job/status.py +24 -0
  45. airbyte_cdk/sources/declarative/async_job/timer.py +39 -0
  46. airbyte_cdk/sources/declarative/auth/__init__.py +2 -3
  47. airbyte_cdk/sources/declarative/auth/declarative_authenticator.py +3 -1
  48. airbyte_cdk/sources/declarative/auth/jwt.py +191 -0
  49. airbyte_cdk/sources/declarative/auth/oauth.py +60 -20
  50. airbyte_cdk/sources/declarative/auth/selective_authenticator.py +10 -2
  51. airbyte_cdk/sources/declarative/auth/token.py +28 -10
  52. airbyte_cdk/sources/declarative/auth/token_provider.py +9 -8
  53. airbyte_cdk/sources/declarative/checks/check_stream.py +16 -8
  54. airbyte_cdk/sources/declarative/checks/connection_checker.py +4 -2
  55. airbyte_cdk/sources/declarative/concurrency_level/__init__.py +7 -0
  56. airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py +50 -0
  57. airbyte_cdk/sources/declarative/concurrent_declarative_source.py +421 -0
  58. airbyte_cdk/sources/declarative/datetime/datetime_parser.py +4 -0
  59. airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +26 -6
  60. airbyte_cdk/sources/declarative/declarative_component_schema.yaml +1185 -85
  61. airbyte_cdk/sources/declarative/declarative_source.py +5 -2
  62. airbyte_cdk/sources/declarative/declarative_stream.py +95 -9
  63. airbyte_cdk/sources/declarative/decoders/__init__.py +23 -2
  64. airbyte_cdk/sources/declarative/decoders/composite_raw_decoder.py +97 -0
  65. airbyte_cdk/sources/declarative/decoders/decoder.py +11 -4
  66. airbyte_cdk/sources/declarative/decoders/json_decoder.py +92 -5
  67. airbyte_cdk/sources/declarative/decoders/noop_decoder.py +21 -0
  68. airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py +39 -0
  69. airbyte_cdk/sources/declarative/decoders/xml_decoder.py +98 -0
  70. airbyte_cdk/sources/declarative/extractors/__init__.py +12 -1
  71. airbyte_cdk/sources/declarative/extractors/dpath_extractor.py +29 -24
  72. airbyte_cdk/sources/declarative/extractors/http_selector.py +4 -5
  73. airbyte_cdk/sources/declarative/extractors/record_extractor.py +2 -3
  74. airbyte_cdk/sources/declarative/extractors/record_filter.py +65 -8
  75. airbyte_cdk/sources/declarative/extractors/record_selector.py +85 -26
  76. airbyte_cdk/sources/declarative/extractors/response_to_file_extractor.py +177 -0
  77. airbyte_cdk/sources/declarative/extractors/type_transformer.py +55 -0
  78. airbyte_cdk/sources/declarative/incremental/__init__.py +25 -3
  79. airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +156 -48
  80. airbyte_cdk/sources/declarative/incremental/declarative_cursor.py +13 -0
  81. airbyte_cdk/sources/declarative/incremental/global_substream_cursor.py +350 -0
  82. airbyte_cdk/sources/declarative/incremental/per_partition_cursor.py +159 -74
  83. airbyte_cdk/sources/declarative/incremental/per_partition_with_global.py +200 -0
  84. airbyte_cdk/sources/declarative/incremental/resumable_full_refresh_cursor.py +122 -0
  85. airbyte_cdk/sources/declarative/interpolation/filters.py +27 -1
  86. airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py +23 -5
  87. airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py +12 -8
  88. airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py +13 -6
  89. airbyte_cdk/sources/declarative/interpolation/interpolated_string.py +21 -6
  90. airbyte_cdk/sources/declarative/interpolation/interpolation.py +9 -3
  91. airbyte_cdk/sources/declarative/interpolation/jinja.py +72 -37
  92. airbyte_cdk/sources/declarative/interpolation/macros.py +72 -17
  93. airbyte_cdk/sources/declarative/manifest_declarative_source.py +193 -52
  94. airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py +98 -0
  95. airbyte_cdk/sources/declarative/migrations/state_migration.py +24 -0
  96. airbyte_cdk/sources/declarative/models/__init__.py +1 -1
  97. airbyte_cdk/sources/declarative/models/declarative_component_schema.py +1319 -603
  98. airbyte_cdk/sources/declarative/parsers/custom_exceptions.py +2 -2
  99. airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +26 -4
  100. airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py +26 -15
  101. airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +1695 -225
  102. airbyte_cdk/sources/declarative/partition_routers/__init__.py +24 -4
  103. airbyte_cdk/sources/declarative/partition_routers/async_job_partition_router.py +65 -0
  104. airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py +176 -0
  105. airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py +39 -9
  106. airbyte_cdk/sources/declarative/partition_routers/partition_router.py +62 -0
  107. airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py +15 -3
  108. airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py +222 -39
  109. airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py +19 -5
  110. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +3 -1
  111. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py +19 -7
  112. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py +19 -7
  113. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py +4 -2
  114. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py +41 -9
  115. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py +29 -14
  116. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py +5 -13
  117. airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py +32 -16
  118. airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py +46 -56
  119. airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_filter.py +40 -0
  120. airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py +6 -32
  121. airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py +119 -41
  122. airbyte_cdk/sources/declarative/requesters/http_job_repository.py +228 -0
  123. airbyte_cdk/sources/declarative/requesters/http_requester.py +98 -344
  124. airbyte_cdk/sources/declarative/requesters/paginators/__init__.py +14 -3
  125. airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +105 -46
  126. airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py +14 -8
  127. airbyte_cdk/sources/declarative/requesters/paginators/paginator.py +19 -8
  128. airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py +9 -3
  129. airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py +53 -21
  130. airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py +42 -19
  131. airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py +25 -12
  132. airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py +13 -10
  133. airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py +26 -13
  134. airbyte_cdk/sources/declarative/requesters/request_options/__init__.py +15 -2
  135. airbyte_cdk/sources/declarative/requesters/request_options/datetime_based_request_options_provider.py +91 -0
  136. airbyte_cdk/sources/declarative/requesters/request_options/default_request_options_provider.py +60 -0
  137. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py +31 -14
  138. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py +27 -15
  139. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py +63 -10
  140. airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +1 -1
  141. airbyte_cdk/sources/declarative/requesters/requester.py +9 -17
  142. airbyte_cdk/sources/declarative/resolvers/__init__.py +41 -0
  143. airbyte_cdk/sources/declarative/resolvers/components_resolver.py +55 -0
  144. airbyte_cdk/sources/declarative/resolvers/config_components_resolver.py +136 -0
  145. airbyte_cdk/sources/declarative/resolvers/http_components_resolver.py +112 -0
  146. airbyte_cdk/sources/declarative/retrievers/__init__.py +6 -2
  147. airbyte_cdk/sources/declarative/retrievers/async_retriever.py +100 -0
  148. airbyte_cdk/sources/declarative/retrievers/retriever.py +1 -3
  149. airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +228 -72
  150. airbyte_cdk/sources/declarative/schema/__init__.py +14 -1
  151. airbyte_cdk/sources/declarative/schema/default_schema_loader.py +5 -3
  152. airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py +236 -0
  153. airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py +8 -8
  154. airbyte_cdk/sources/declarative/spec/spec.py +12 -5
  155. airbyte_cdk/sources/declarative/stream_slicers/__init__.py +1 -2
  156. airbyte_cdk/sources/declarative/stream_slicers/declarative_partition_generator.py +88 -0
  157. airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py +9 -14
  158. airbyte_cdk/sources/declarative/transformations/add_fields.py +19 -11
  159. airbyte_cdk/sources/declarative/transformations/flatten_fields.py +52 -0
  160. airbyte_cdk/sources/declarative/transformations/keys_replace_transformation.py +61 -0
  161. airbyte_cdk/sources/declarative/transformations/keys_to_lower_transformation.py +22 -0
  162. airbyte_cdk/sources/declarative/transformations/keys_to_snake_transformation.py +68 -0
  163. airbyte_cdk/sources/declarative/transformations/remove_fields.py +13 -10
  164. airbyte_cdk/sources/declarative/transformations/transformation.py +5 -5
  165. airbyte_cdk/sources/declarative/types.py +19 -110
  166. airbyte_cdk/sources/declarative/yaml_declarative_source.py +31 -10
  167. airbyte_cdk/sources/embedded/base_integration.py +16 -5
  168. airbyte_cdk/sources/embedded/catalog.py +16 -4
  169. airbyte_cdk/sources/embedded/runner.py +19 -3
  170. airbyte_cdk/sources/embedded/tools.py +5 -2
  171. airbyte_cdk/sources/file_based/README.md +152 -0
  172. airbyte_cdk/sources/file_based/__init__.py +24 -0
  173. airbyte_cdk/sources/file_based/availability_strategy/__init__.py +9 -2
  174. airbyte_cdk/sources/file_based/availability_strategy/abstract_file_based_availability_strategy.py +22 -6
  175. airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availability_strategy.py +46 -10
  176. airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py +58 -10
  177. airbyte_cdk/sources/file_based/config/avro_format.py +2 -1
  178. airbyte_cdk/sources/file_based/config/csv_format.py +29 -10
  179. airbyte_cdk/sources/file_based/config/excel_format.py +18 -0
  180. airbyte_cdk/sources/file_based/config/file_based_stream_config.py +16 -4
  181. airbyte_cdk/sources/file_based/config/jsonl_format.py +2 -1
  182. airbyte_cdk/sources/file_based/config/parquet_format.py +2 -1
  183. airbyte_cdk/sources/file_based/config/unstructured_format.py +13 -5
  184. airbyte_cdk/sources/file_based/discovery_policy/__init__.py +6 -2
  185. airbyte_cdk/sources/file_based/discovery_policy/abstract_discovery_policy.py +2 -4
  186. airbyte_cdk/sources/file_based/discovery_policy/default_discovery_policy.py +7 -2
  187. airbyte_cdk/sources/file_based/exceptions.py +52 -15
  188. airbyte_cdk/sources/file_based/file_based_source.py +163 -33
  189. airbyte_cdk/sources/file_based/file_based_stream_reader.py +83 -5
  190. airbyte_cdk/sources/file_based/file_types/__init__.py +14 -1
  191. airbyte_cdk/sources/file_based/file_types/avro_parser.py +75 -24
  192. airbyte_cdk/sources/file_based/file_types/csv_parser.py +116 -34
  193. airbyte_cdk/sources/file_based/file_types/excel_parser.py +196 -0
  194. airbyte_cdk/sources/file_based/file_types/file_transfer.py +37 -0
  195. airbyte_cdk/sources/file_based/file_types/file_type_parser.py +4 -1
  196. airbyte_cdk/sources/file_based/file_types/jsonl_parser.py +24 -8
  197. airbyte_cdk/sources/file_based/file_types/parquet_parser.py +60 -18
  198. airbyte_cdk/sources/file_based/file_types/unstructured_parser.py +145 -41
  199. airbyte_cdk/sources/file_based/remote_file.py +1 -1
  200. airbyte_cdk/sources/file_based/schema_helpers.py +38 -10
  201. airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py +3 -1
  202. airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py +3 -1
  203. airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py +16 -5
  204. airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py +50 -13
  205. airbyte_cdk/sources/file_based/stream/concurrent/adapters.py +67 -27
  206. airbyte_cdk/sources/file_based/stream/concurrent/cursor/__init__.py +5 -1
  207. airbyte_cdk/sources/file_based/stream/concurrent/cursor/abstract_concurrent_file_based_cursor.py +14 -23
  208. airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py +54 -18
  209. airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_final_state_cursor.py +21 -9
  210. airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py +3 -1
  211. airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py +27 -10
  212. airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +175 -45
  213. airbyte_cdk/sources/http_logger.py +8 -3
  214. airbyte_cdk/sources/message/__init__.py +7 -1
  215. airbyte_cdk/sources/message/repository.py +18 -4
  216. airbyte_cdk/sources/source.py +42 -38
  217. airbyte_cdk/sources/streams/__init__.py +2 -2
  218. airbyte_cdk/sources/streams/availability_strategy.py +54 -3
  219. airbyte_cdk/sources/streams/call_rate.py +64 -21
  220. airbyte_cdk/sources/streams/checkpoint/__init__.py +26 -0
  221. airbyte_cdk/sources/streams/checkpoint/checkpoint_reader.py +335 -0
  222. airbyte_cdk/sources/{declarative/incremental → streams/checkpoint}/cursor.py +17 -14
  223. airbyte_cdk/sources/streams/checkpoint/per_partition_key_serializer.py +22 -0
  224. airbyte_cdk/sources/streams/checkpoint/resumable_full_refresh_cursor.py +51 -0
  225. airbyte_cdk/sources/streams/checkpoint/substream_resumable_full_refresh_cursor.py +110 -0
  226. airbyte_cdk/sources/streams/concurrent/README.md +7 -0
  227. airbyte_cdk/sources/streams/concurrent/abstract_stream.py +7 -2
  228. airbyte_cdk/sources/streams/concurrent/adapters.py +84 -75
  229. airbyte_cdk/sources/streams/concurrent/availability_strategy.py +30 -2
  230. airbyte_cdk/sources/streams/concurrent/cursor.py +298 -42
  231. airbyte_cdk/sources/streams/concurrent/default_stream.py +12 -3
  232. airbyte_cdk/sources/streams/concurrent/exceptions.py +3 -0
  233. airbyte_cdk/sources/streams/concurrent/helpers.py +14 -3
  234. airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py +12 -3
  235. airbyte_cdk/sources/streams/concurrent/partition_reader.py +10 -3
  236. airbyte_cdk/sources/streams/concurrent/partitions/partition.py +1 -16
  237. airbyte_cdk/sources/streams/concurrent/partitions/stream_slicer.py +21 -0
  238. airbyte_cdk/sources/streams/concurrent/partitions/types.py +15 -5
  239. airbyte_cdk/sources/streams/concurrent/state_converters/abstract_stream_state_converter.py +109 -17
  240. airbyte_cdk/sources/streams/concurrent/state_converters/datetime_stream_state_converter.py +90 -72
  241. airbyte_cdk/sources/streams/core.py +412 -87
  242. airbyte_cdk/sources/streams/http/__init__.py +2 -1
  243. airbyte_cdk/sources/streams/http/availability_strategy.py +12 -101
  244. airbyte_cdk/sources/streams/http/error_handlers/__init__.py +22 -0
  245. airbyte_cdk/sources/streams/http/error_handlers/backoff_strategy.py +28 -0
  246. airbyte_cdk/sources/streams/http/error_handlers/default_backoff_strategy.py +17 -0
  247. airbyte_cdk/sources/streams/http/error_handlers/default_error_mapping.py +86 -0
  248. airbyte_cdk/sources/streams/http/error_handlers/error_handler.py +42 -0
  249. airbyte_cdk/sources/streams/http/error_handlers/error_message_parser.py +19 -0
  250. airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py +110 -0
  251. airbyte_cdk/sources/streams/http/error_handlers/json_error_message_parser.py +52 -0
  252. airbyte_cdk/sources/streams/http/error_handlers/response_models.py +65 -0
  253. airbyte_cdk/sources/streams/http/exceptions.py +27 -7
  254. airbyte_cdk/sources/streams/http/http.py +369 -246
  255. airbyte_cdk/sources/streams/http/http_client.py +531 -0
  256. airbyte_cdk/sources/streams/http/rate_limiting.py +76 -12
  257. airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +28 -9
  258. airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py +2 -1
  259. airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +90 -35
  260. airbyte_cdk/sources/streams/http/requests_native_auth/token.py +13 -3
  261. airbyte_cdk/sources/types.py +154 -0
  262. airbyte_cdk/sources/utils/record_helper.py +36 -21
  263. airbyte_cdk/sources/utils/schema_helpers.py +13 -6
  264. airbyte_cdk/sources/utils/slice_logger.py +4 -1
  265. airbyte_cdk/sources/utils/transform.py +54 -20
  266. airbyte_cdk/sql/_util/hashing.py +34 -0
  267. airbyte_cdk/sql/_util/name_normalizers.py +92 -0
  268. airbyte_cdk/sql/constants.py +32 -0
  269. airbyte_cdk/sql/exceptions.py +235 -0
  270. airbyte_cdk/sql/secrets.py +123 -0
  271. airbyte_cdk/sql/shared/__init__.py +15 -0
  272. airbyte_cdk/sql/shared/catalog_providers.py +145 -0
  273. airbyte_cdk/sql/shared/sql_processor.py +786 -0
  274. airbyte_cdk/sql/types.py +160 -0
  275. airbyte_cdk/test/catalog_builder.py +70 -18
  276. airbyte_cdk/test/entrypoint_wrapper.py +117 -42
  277. airbyte_cdk/test/mock_http/__init__.py +1 -1
  278. airbyte_cdk/test/mock_http/matcher.py +6 -0
  279. airbyte_cdk/test/mock_http/mocker.py +57 -10
  280. airbyte_cdk/test/mock_http/request.py +19 -3
  281. airbyte_cdk/test/mock_http/response.py +3 -1
  282. airbyte_cdk/test/mock_http/response_builder.py +32 -16
  283. airbyte_cdk/test/state_builder.py +18 -10
  284. airbyte_cdk/test/utils/__init__.py +1 -0
  285. airbyte_cdk/test/utils/data.py +24 -0
  286. airbyte_cdk/test/utils/http_mocking.py +16 -0
  287. airbyte_cdk/test/utils/manifest_only_fixtures.py +60 -0
  288. airbyte_cdk/test/utils/reading.py +26 -0
  289. airbyte_cdk/utils/__init__.py +2 -1
  290. airbyte_cdk/utils/airbyte_secrets_utils.py +5 -3
  291. airbyte_cdk/utils/analytics_message.py +10 -2
  292. airbyte_cdk/utils/datetime_format_inferrer.py +4 -1
  293. airbyte_cdk/utils/event_timing.py +10 -10
  294. airbyte_cdk/utils/mapping_helpers.py +3 -1
  295. airbyte_cdk/utils/message_utils.py +20 -11
  296. airbyte_cdk/utils/print_buffer.py +75 -0
  297. airbyte_cdk/utils/schema_inferrer.py +198 -28
  298. airbyte_cdk/utils/slice_hasher.py +30 -0
  299. airbyte_cdk/utils/spec_schema_transformations.py +6 -3
  300. airbyte_cdk/utils/stream_status_utils.py +8 -1
  301. airbyte_cdk/utils/traced_exception.py +61 -21
  302. airbyte_cdk-6.13.1.dev4106.dist-info/METADATA +109 -0
  303. airbyte_cdk-6.13.1.dev4106.dist-info/RECORD +349 -0
  304. {airbyte_cdk-0.72.1.dist-info → airbyte_cdk-6.13.1.dev4106.dist-info}/WHEEL +1 -2
  305. airbyte_cdk-6.13.1.dev4106.dist-info/entry_points.txt +3 -0
  306. airbyte_cdk/sources/declarative/create_partial.py +0 -92
  307. airbyte_cdk/sources/declarative/parsers/class_types_registry.py +0 -102
  308. airbyte_cdk/sources/declarative/parsers/default_implementation_registry.py +0 -64
  309. airbyte_cdk/sources/declarative/requesters/error_handlers/response_action.py +0 -16
  310. airbyte_cdk/sources/declarative/requesters/error_handlers/response_status.py +0 -68
  311. airbyte_cdk/sources/declarative/stream_slicers/cartesian_product_stream_slicer.py +0 -114
  312. airbyte_cdk/sources/deprecated/base_source.py +0 -94
  313. airbyte_cdk/sources/deprecated/client.py +0 -99
  314. airbyte_cdk/sources/singer/__init__.py +0 -8
  315. airbyte_cdk/sources/singer/singer_helpers.py +0 -304
  316. airbyte_cdk/sources/singer/source.py +0 -186
  317. airbyte_cdk/sources/streams/concurrent/partitions/record.py +0 -23
  318. airbyte_cdk/sources/streams/http/auth/__init__.py +0 -17
  319. airbyte_cdk/sources/streams/http/auth/core.py +0 -29
  320. airbyte_cdk/sources/streams/http/auth/oauth.py +0 -113
  321. airbyte_cdk/sources/streams/http/auth/token.py +0 -47
  322. airbyte_cdk/sources/streams/utils/stream_helper.py +0 -40
  323. airbyte_cdk/sources/utils/catalog_helpers.py +0 -22
  324. airbyte_cdk/sources/utils/schema_models.py +0 -84
  325. airbyte_cdk-0.72.1.dist-info/METADATA +0 -243
  326. airbyte_cdk-0.72.1.dist-info/RECORD +0 -466
  327. airbyte_cdk-0.72.1.dist-info/top_level.txt +0 -3
  328. source_declarative_manifest/main.py +0 -29
  329. unit_tests/connector_builder/__init__.py +0 -3
  330. unit_tests/connector_builder/test_connector_builder_handler.py +0 -871
  331. unit_tests/connector_builder/test_message_grouper.py +0 -713
  332. unit_tests/connector_builder/utils.py +0 -27
  333. unit_tests/destinations/test_destination.py +0 -243
  334. unit_tests/singer/test_singer_helpers.py +0 -56
  335. unit_tests/singer/test_singer_source.py +0 -112
  336. unit_tests/sources/__init__.py +0 -0
  337. unit_tests/sources/concurrent_source/__init__.py +0 -3
  338. unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py +0 -106
  339. unit_tests/sources/declarative/__init__.py +0 -3
  340. unit_tests/sources/declarative/auth/__init__.py +0 -3
  341. unit_tests/sources/declarative/auth/test_oauth.py +0 -331
  342. unit_tests/sources/declarative/auth/test_selective_authenticator.py +0 -39
  343. unit_tests/sources/declarative/auth/test_session_token_auth.py +0 -182
  344. unit_tests/sources/declarative/auth/test_token_auth.py +0 -200
  345. unit_tests/sources/declarative/auth/test_token_provider.py +0 -73
  346. unit_tests/sources/declarative/checks/__init__.py +0 -3
  347. unit_tests/sources/declarative/checks/test_check_stream.py +0 -146
  348. unit_tests/sources/declarative/decoders/__init__.py +0 -0
  349. unit_tests/sources/declarative/decoders/test_json_decoder.py +0 -16
  350. unit_tests/sources/declarative/external_component.py +0 -13
  351. unit_tests/sources/declarative/extractors/__init__.py +0 -3
  352. unit_tests/sources/declarative/extractors/test_dpath_extractor.py +0 -55
  353. unit_tests/sources/declarative/extractors/test_record_filter.py +0 -55
  354. unit_tests/sources/declarative/extractors/test_record_selector.py +0 -179
  355. unit_tests/sources/declarative/incremental/__init__.py +0 -0
  356. unit_tests/sources/declarative/incremental/test_datetime_based_cursor.py +0 -860
  357. unit_tests/sources/declarative/incremental/test_per_partition_cursor.py +0 -406
  358. unit_tests/sources/declarative/incremental/test_per_partition_cursor_integration.py +0 -332
  359. unit_tests/sources/declarative/interpolation/__init__.py +0 -3
  360. unit_tests/sources/declarative/interpolation/test_filters.py +0 -80
  361. unit_tests/sources/declarative/interpolation/test_interpolated_boolean.py +0 -40
  362. unit_tests/sources/declarative/interpolation/test_interpolated_mapping.py +0 -35
  363. unit_tests/sources/declarative/interpolation/test_interpolated_nested_mapping.py +0 -45
  364. unit_tests/sources/declarative/interpolation/test_interpolated_string.py +0 -25
  365. unit_tests/sources/declarative/interpolation/test_jinja.py +0 -240
  366. unit_tests/sources/declarative/interpolation/test_macros.py +0 -73
  367. unit_tests/sources/declarative/parsers/__init__.py +0 -3
  368. unit_tests/sources/declarative/parsers/test_manifest_component_transformer.py +0 -406
  369. unit_tests/sources/declarative/parsers/test_manifest_reference_resolver.py +0 -139
  370. unit_tests/sources/declarative/parsers/test_model_to_component_factory.py +0 -1847
  371. unit_tests/sources/declarative/parsers/testing_components.py +0 -36
  372. unit_tests/sources/declarative/partition_routers/__init__.py +0 -3
  373. unit_tests/sources/declarative/partition_routers/test_list_partition_router.py +0 -155
  374. unit_tests/sources/declarative/partition_routers/test_single_partition_router.py +0 -14
  375. unit_tests/sources/declarative/partition_routers/test_substream_partition_router.py +0 -404
  376. unit_tests/sources/declarative/requesters/__init__.py +0 -3
  377. unit_tests/sources/declarative/requesters/error_handlers/__init__.py +0 -3
  378. unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +0 -3
  379. unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_constant_backoff.py +0 -34
  380. unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_exponential_backoff.py +0 -36
  381. unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_header_helper.py +0 -38
  382. unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_time_from_header.py +0 -35
  383. unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_until_time_from_header.py +0 -64
  384. unit_tests/sources/declarative/requesters/error_handlers/test_composite_error_handler.py +0 -213
  385. unit_tests/sources/declarative/requesters/error_handlers/test_default_error_handler.py +0 -178
  386. unit_tests/sources/declarative/requesters/error_handlers/test_http_response_filter.py +0 -121
  387. unit_tests/sources/declarative/requesters/error_handlers/test_response_status.py +0 -44
  388. unit_tests/sources/declarative/requesters/paginators/__init__.py +0 -3
  389. unit_tests/sources/declarative/requesters/paginators/test_cursor_pagination_strategy.py +0 -64
  390. unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py +0 -313
  391. unit_tests/sources/declarative/requesters/paginators/test_no_paginator.py +0 -12
  392. unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py +0 -58
  393. unit_tests/sources/declarative/requesters/paginators/test_page_increment.py +0 -70
  394. unit_tests/sources/declarative/requesters/paginators/test_request_option.py +0 -43
  395. unit_tests/sources/declarative/requesters/paginators/test_stop_condition.py +0 -105
  396. unit_tests/sources/declarative/requesters/request_options/__init__.py +0 -3
  397. unit_tests/sources/declarative/requesters/request_options/test_interpolated_request_options_provider.py +0 -101
  398. unit_tests/sources/declarative/requesters/test_http_requester.py +0 -974
  399. unit_tests/sources/declarative/requesters/test_interpolated_request_input_provider.py +0 -32
  400. unit_tests/sources/declarative/retrievers/__init__.py +0 -3
  401. unit_tests/sources/declarative/retrievers/test_simple_retriever.py +0 -542
  402. unit_tests/sources/declarative/schema/__init__.py +0 -6
  403. unit_tests/sources/declarative/schema/source_test/SourceTest.py +0 -8
  404. unit_tests/sources/declarative/schema/source_test/__init__.py +0 -3
  405. unit_tests/sources/declarative/schema/test_default_schema_loader.py +0 -32
  406. unit_tests/sources/declarative/schema/test_inline_schema_loader.py +0 -19
  407. unit_tests/sources/declarative/schema/test_json_file_schema_loader.py +0 -26
  408. unit_tests/sources/declarative/states/__init__.py +0 -3
  409. unit_tests/sources/declarative/stream_slicers/__init__.py +0 -3
  410. unit_tests/sources/declarative/stream_slicers/test_cartesian_product_stream_slicer.py +0 -225
  411. unit_tests/sources/declarative/test_create_partial.py +0 -83
  412. unit_tests/sources/declarative/test_declarative_stream.py +0 -103
  413. unit_tests/sources/declarative/test_manifest_declarative_source.py +0 -1260
  414. unit_tests/sources/declarative/test_types.py +0 -39
  415. unit_tests/sources/declarative/test_yaml_declarative_source.py +0 -148
  416. unit_tests/sources/file_based/__init__.py +0 -0
  417. unit_tests/sources/file_based/availability_strategy/__init__.py +0 -0
  418. unit_tests/sources/file_based/availability_strategy/test_default_file_based_availability_strategy.py +0 -100
  419. unit_tests/sources/file_based/config/__init__.py +0 -0
  420. unit_tests/sources/file_based/config/test_abstract_file_based_spec.py +0 -28
  421. unit_tests/sources/file_based/config/test_csv_format.py +0 -34
  422. unit_tests/sources/file_based/config/test_file_based_stream_config.py +0 -84
  423. unit_tests/sources/file_based/discovery_policy/__init__.py +0 -0
  424. unit_tests/sources/file_based/discovery_policy/test_default_discovery_policy.py +0 -31
  425. unit_tests/sources/file_based/file_types/__init__.py +0 -0
  426. unit_tests/sources/file_based/file_types/test_avro_parser.py +0 -243
  427. unit_tests/sources/file_based/file_types/test_csv_parser.py +0 -546
  428. unit_tests/sources/file_based/file_types/test_jsonl_parser.py +0 -158
  429. unit_tests/sources/file_based/file_types/test_parquet_parser.py +0 -274
  430. unit_tests/sources/file_based/file_types/test_unstructured_parser.py +0 -593
  431. unit_tests/sources/file_based/helpers.py +0 -70
  432. unit_tests/sources/file_based/in_memory_files_source.py +0 -211
  433. unit_tests/sources/file_based/scenarios/__init__.py +0 -0
  434. unit_tests/sources/file_based/scenarios/avro_scenarios.py +0 -744
  435. unit_tests/sources/file_based/scenarios/check_scenarios.py +0 -220
  436. unit_tests/sources/file_based/scenarios/concurrent_incremental_scenarios.py +0 -2844
  437. unit_tests/sources/file_based/scenarios/csv_scenarios.py +0 -3105
  438. unit_tests/sources/file_based/scenarios/file_based_source_builder.py +0 -91
  439. unit_tests/sources/file_based/scenarios/incremental_scenarios.py +0 -1926
  440. unit_tests/sources/file_based/scenarios/jsonl_scenarios.py +0 -930
  441. unit_tests/sources/file_based/scenarios/parquet_scenarios.py +0 -754
  442. unit_tests/sources/file_based/scenarios/scenario_builder.py +0 -234
  443. unit_tests/sources/file_based/scenarios/unstructured_scenarios.py +0 -608
  444. unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py +0 -746
  445. unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py +0 -726
  446. unit_tests/sources/file_based/stream/__init__.py +0 -0
  447. unit_tests/sources/file_based/stream/concurrent/__init__.py +0 -0
  448. unit_tests/sources/file_based/stream/concurrent/test_adapters.py +0 -362
  449. unit_tests/sources/file_based/stream/concurrent/test_file_based_concurrent_cursor.py +0 -458
  450. unit_tests/sources/file_based/stream/test_default_file_based_cursor.py +0 -310
  451. unit_tests/sources/file_based/stream/test_default_file_based_stream.py +0 -244
  452. unit_tests/sources/file_based/test_file_based_scenarios.py +0 -320
  453. unit_tests/sources/file_based/test_file_based_stream_reader.py +0 -272
  454. unit_tests/sources/file_based/test_scenarios.py +0 -253
  455. unit_tests/sources/file_based/test_schema_helpers.py +0 -346
  456. unit_tests/sources/fixtures/__init__.py +0 -3
  457. unit_tests/sources/fixtures/source_test_fixture.py +0 -153
  458. unit_tests/sources/message/__init__.py +0 -0
  459. unit_tests/sources/message/test_repository.py +0 -153
  460. unit_tests/sources/streams/__init__.py +0 -0
  461. unit_tests/sources/streams/concurrent/__init__.py +0 -3
  462. unit_tests/sources/streams/concurrent/scenarios/__init__.py +0 -3
  463. unit_tests/sources/streams/concurrent/scenarios/incremental_scenarios.py +0 -250
  464. unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py +0 -140
  465. unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py +0 -452
  466. unit_tests/sources/streams/concurrent/scenarios/test_concurrent_scenarios.py +0 -76
  467. unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py +0 -418
  468. unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py +0 -142
  469. unit_tests/sources/streams/concurrent/scenarios/utils.py +0 -55
  470. unit_tests/sources/streams/concurrent/test_adapters.py +0 -380
  471. unit_tests/sources/streams/concurrent/test_concurrent_read_processor.py +0 -684
  472. unit_tests/sources/streams/concurrent/test_cursor.py +0 -139
  473. unit_tests/sources/streams/concurrent/test_datetime_state_converter.py +0 -369
  474. unit_tests/sources/streams/concurrent/test_default_stream.py +0 -197
  475. unit_tests/sources/streams/concurrent/test_partition_enqueuer.py +0 -90
  476. unit_tests/sources/streams/concurrent/test_partition_reader.py +0 -67
  477. unit_tests/sources/streams/concurrent/test_thread_pool_manager.py +0 -106
  478. unit_tests/sources/streams/http/__init__.py +0 -0
  479. unit_tests/sources/streams/http/auth/__init__.py +0 -0
  480. unit_tests/sources/streams/http/auth/test_auth.py +0 -173
  481. unit_tests/sources/streams/http/requests_native_auth/__init__.py +0 -0
  482. unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py +0 -423
  483. unit_tests/sources/streams/http/test_availability_strategy.py +0 -180
  484. unit_tests/sources/streams/http/test_http.py +0 -635
  485. unit_tests/sources/streams/test_availability_strategy.py +0 -70
  486. unit_tests/sources/streams/test_call_rate.py +0 -300
  487. unit_tests/sources/streams/test_stream_read.py +0 -405
  488. unit_tests/sources/streams/test_streams_core.py +0 -184
  489. unit_tests/sources/test_abstract_source.py +0 -1442
  490. unit_tests/sources/test_concurrent_source.py +0 -112
  491. unit_tests/sources/test_config.py +0 -92
  492. unit_tests/sources/test_connector_state_manager.py +0 -482
  493. unit_tests/sources/test_http_logger.py +0 -252
  494. unit_tests/sources/test_integration_source.py +0 -86
  495. unit_tests/sources/test_source.py +0 -684
  496. unit_tests/sources/test_source_read.py +0 -460
  497. unit_tests/test/__init__.py +0 -0
  498. unit_tests/test/mock_http/__init__.py +0 -0
  499. unit_tests/test/mock_http/test_matcher.py +0 -53
  500. unit_tests/test/mock_http/test_mocker.py +0 -214
  501. unit_tests/test/mock_http/test_request.py +0 -117
  502. unit_tests/test/mock_http/test_response_builder.py +0 -177
  503. unit_tests/test/test_entrypoint_wrapper.py +0 -240
  504. unit_tests/utils/__init__.py +0 -0
  505. unit_tests/utils/test_datetime_format_inferrer.py +0 -60
  506. unit_tests/utils/test_mapping_helpers.py +0 -54
  507. unit_tests/utils/test_message_utils.py +0 -91
  508. unit_tests/utils/test_rate_limiting.py +0 -26
  509. unit_tests/utils/test_schema_inferrer.py +0 -202
  510. unit_tests/utils/test_secret_utils.py +0 -135
  511. unit_tests/utils/test_stream_status_utils.py +0 -61
  512. unit_tests/utils/test_traced_exception.py +0 -107
  513. /airbyte_cdk/sources/{deprecated → declarative/async_job}/__init__.py +0 -0
  514. {source_declarative_manifest → airbyte_cdk/sources/declarative/migrations}/__init__.py +0 -0
  515. {unit_tests/destinations → airbyte_cdk/sql}/__init__.py +0 -0
  516. {unit_tests/singer → airbyte_cdk/sql/_util}/__init__.py +0 -0
  517. {airbyte_cdk-0.72.1.dist-info → airbyte_cdk-6.13.1.dev4106.dist-info}/LICENSE.txt +0 -0
airbyte_cdk/entrypoint.py CHANGED
@@ -5,6 +5,7 @@
5
5
  import argparse
6
6
  import importlib
7
7
  import ipaddress
8
+ import json
8
9
  import logging
9
10
  import os.path
10
11
  import socket
@@ -12,35 +13,48 @@ import sys
12
13
  import tempfile
13
14
  from collections import defaultdict
14
15
  from functools import wraps
15
- from typing import Any, DefaultDict, Iterable, List, Mapping, MutableMapping, Optional, Union
16
+ from typing import Any, DefaultDict, Iterable, List, Mapping, Optional
16
17
  from urllib.parse import urlparse
17
18
 
19
+ import orjson
18
20
  import requests
21
+ from requests import PreparedRequest, Response, Session
22
+
19
23
  from airbyte_cdk.connector import TConfig
20
24
  from airbyte_cdk.exception_handler import init_uncaught_exception_handler
21
25
  from airbyte_cdk.logger import init_logger
22
- from airbyte_cdk.models import AirbyteMessage, FailureType, Status, Type
23
- from airbyte_cdk.models.airbyte_protocol import AirbyteStateStats, ConnectorSpecification # type: ignore [attr-defined]
26
+ from airbyte_cdk.models import (
27
+ AirbyteConnectionStatus,
28
+ AirbyteMessage,
29
+ AirbyteMessageSerializer,
30
+ AirbyteStateStats,
31
+ ConnectorSpecification,
32
+ FailureType,
33
+ Status,
34
+ Type,
35
+ )
24
36
  from airbyte_cdk.sources import Source
25
37
  from airbyte_cdk.sources.connector_state_manager import HashableStreamDescriptor
26
38
  from airbyte_cdk.sources.utils.schema_helpers import check_config_against_spec_or_exit, split_config
39
+
40
+ # from airbyte_cdk.utils import PrintBuffer, is_cloud_environment, message_utils # add PrintBuffer back once fixed
27
41
  from airbyte_cdk.utils import is_cloud_environment, message_utils
28
42
  from airbyte_cdk.utils.airbyte_secrets_utils import get_secrets, update_secrets
29
43
  from airbyte_cdk.utils.constants import ENV_REQUEST_CACHE_PATH
30
44
  from airbyte_cdk.utils.traced_exception import AirbyteTracedException
31
- from requests import PreparedRequest, Response, Session
32
45
 
33
46
  logger = init_logger("airbyte")
34
47
 
35
48
  VALID_URL_SCHEMES = ["https"]
36
49
  CLOUD_DEPLOYMENT_MODE = "cloud"
50
+ _HAS_LOGGED_FOR_SERIALIZATION_ERROR = False
37
51
 
38
52
 
39
53
  class AirbyteEntrypoint(object):
40
54
  def __init__(self, source: Source):
41
55
  init_uncaught_exception_handler(logger)
42
56
 
43
- # deployment mode is read when instantiating the entrypoint because it is the common path shared by syncs and connector builder test requests
57
+ # Deployment mode is read when instantiating the entrypoint because it is the common path shared by syncs and connector builder test requests
44
58
  if is_cloud_environment():
45
59
  _init_internal_request_filter()
46
60
 
@@ -51,33 +65,54 @@ class AirbyteEntrypoint(object):
51
65
  def parse_args(args: List[str]) -> argparse.Namespace:
52
66
  # set up parent parsers
53
67
  parent_parser = argparse.ArgumentParser(add_help=False)
54
- parent_parser.add_argument("--debug", action="store_true", help="enables detailed debug logs related to the sync")
68
+ parent_parser.add_argument(
69
+ "--debug", action="store_true", help="enables detailed debug logs related to the sync"
70
+ )
55
71
  main_parser = argparse.ArgumentParser()
56
72
  subparsers = main_parser.add_subparsers(title="commands", dest="command")
57
73
 
58
74
  # spec
59
- subparsers.add_parser("spec", help="outputs the json configuration specification", parents=[parent_parser])
75
+ subparsers.add_parser(
76
+ "spec", help="outputs the json configuration specification", parents=[parent_parser]
77
+ )
60
78
 
61
79
  # check
62
- check_parser = subparsers.add_parser("check", help="checks the config can be used to connect", parents=[parent_parser])
80
+ check_parser = subparsers.add_parser(
81
+ "check", help="checks the config can be used to connect", parents=[parent_parser]
82
+ )
63
83
  required_check_parser = check_parser.add_argument_group("required named arguments")
64
- required_check_parser.add_argument("--config", type=str, required=True, help="path to the json configuration file")
84
+ required_check_parser.add_argument(
85
+ "--config", type=str, required=True, help="path to the json configuration file"
86
+ )
65
87
 
66
88
  # discover
67
89
  discover_parser = subparsers.add_parser(
68
- "discover", help="outputs a catalog describing the source's schema", parents=[parent_parser]
90
+ "discover",
91
+ help="outputs a catalog describing the source's schema",
92
+ parents=[parent_parser],
69
93
  )
70
94
  required_discover_parser = discover_parser.add_argument_group("required named arguments")
71
- required_discover_parser.add_argument("--config", type=str, required=True, help="path to the json configuration file")
95
+ required_discover_parser.add_argument(
96
+ "--config", type=str, required=True, help="path to the json configuration file"
97
+ )
72
98
 
73
99
  # read
74
- read_parser = subparsers.add_parser("read", help="reads the source and outputs messages to STDOUT", parents=[parent_parser])
100
+ read_parser = subparsers.add_parser(
101
+ "read", help="reads the source and outputs messages to STDOUT", parents=[parent_parser]
102
+ )
75
103
 
76
- read_parser.add_argument("--state", type=str, required=False, help="path to the json-encoded state file")
104
+ read_parser.add_argument(
105
+ "--state", type=str, required=False, help="path to the json-encoded state file"
106
+ )
77
107
  required_read_parser = read_parser.add_argument_group("required named arguments")
78
- required_read_parser.add_argument("--config", type=str, required=True, help="path to the json configuration file")
79
108
  required_read_parser.add_argument(
80
- "--catalog", type=str, required=True, help="path to the catalog used to determine which data to read"
109
+ "--config", type=str, required=True, help="path to the json configuration file"
110
+ )
111
+ required_read_parser.add_argument(
112
+ "--catalog",
113
+ type=str,
114
+ required=True,
115
+ help="path to the catalog used to determine which data to read",
81
116
  )
82
117
 
83
118
  return main_parser.parse_args(args)
@@ -96,12 +131,19 @@ class AirbyteEntrypoint(object):
96
131
 
97
132
  source_spec: ConnectorSpecification = self.source.spec(self.logger)
98
133
  try:
99
- with tempfile.TemporaryDirectory() as temp_dir:
100
- os.environ[ENV_REQUEST_CACHE_PATH] = temp_dir # set this as default directory for request_cache to store *.sqlite files
134
+ with tempfile.TemporaryDirectory(
135
+ # Cleanup can fail on Windows due to file locks. Ignore if so,
136
+ # rather than failing the whole process.
137
+ ignore_cleanup_errors=True,
138
+ ) as temp_dir:
139
+ os.environ[ENV_REQUEST_CACHE_PATH] = (
140
+ temp_dir # set this as default directory for request_cache to store *.sqlite files
141
+ )
101
142
  if cmd == "spec":
102
143
  message = AirbyteMessage(type=Type.SPEC, spec=source_spec)
103
144
  yield from [
104
- self.airbyte_message_to_string(queued_message) for queued_message in self._emit_queued_messages(self.source)
145
+ self.airbyte_message_to_string(queued_message)
146
+ for queued_message in self._emit_queued_messages(self.source)
105
147
  ]
106
148
  yield self.airbyte_message_to_string(message)
107
149
  else:
@@ -109,34 +151,68 @@ class AirbyteEntrypoint(object):
109
151
  config = self.source.configure(raw_config, temp_dir)
110
152
 
111
153
  yield from [
112
- self.airbyte_message_to_string(queued_message) for queued_message in self._emit_queued_messages(self.source)
154
+ self.airbyte_message_to_string(queued_message)
155
+ for queued_message in self._emit_queued_messages(self.source)
113
156
  ]
114
157
  if cmd == "check":
115
- yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.check(source_spec, config))
158
+ yield from map(
159
+ AirbyteEntrypoint.airbyte_message_to_string,
160
+ self.check(source_spec, config),
161
+ )
116
162
  elif cmd == "discover":
117
- yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.discover(source_spec, config))
163
+ yield from map(
164
+ AirbyteEntrypoint.airbyte_message_to_string,
165
+ self.discover(source_spec, config),
166
+ )
118
167
  elif cmd == "read":
119
168
  config_catalog = self.source.read_catalog(parsed_args.catalog)
120
169
  state = self.source.read_state(parsed_args.state)
121
170
 
122
- yield from map(AirbyteEntrypoint.airbyte_message_to_string, self.read(source_spec, config, config_catalog, state))
171
+ yield from map(
172
+ AirbyteEntrypoint.airbyte_message_to_string,
173
+ self.read(source_spec, config, config_catalog, state),
174
+ )
123
175
  else:
124
176
  raise Exception("Unexpected command " + cmd)
125
177
  finally:
126
- yield from [self.airbyte_message_to_string(queued_message) for queued_message in self._emit_queued_messages(self.source)]
178
+ yield from [
179
+ self.airbyte_message_to_string(queued_message)
180
+ for queued_message in self._emit_queued_messages(self.source)
181
+ ]
127
182
 
128
- def check(self, source_spec: ConnectorSpecification, config: TConfig) -> Iterable[AirbyteMessage]:
183
+ def check(
184
+ self, source_spec: ConnectorSpecification, config: TConfig
185
+ ) -> Iterable[AirbyteMessage]:
129
186
  self.set_up_secret_filter(config, source_spec.connectionSpecification)
130
187
  try:
131
188
  self.validate_connection(source_spec, config)
132
189
  except AirbyteTracedException as traced_exc:
133
190
  connection_status = traced_exc.as_connection_status_message()
191
+ # The platform uses the exit code to surface unexpected failures so we raise the exception if the failure type not a config error
192
+ # If the failure is not exceptional, we'll emit a failed connection status message and return
193
+ if traced_exc.failure_type != FailureType.config_error:
194
+ raise traced_exc
134
195
  if connection_status:
135
196
  yield from self._emit_queued_messages(self.source)
136
197
  yield connection_status
137
198
  return
138
199
 
139
- check_result = self.source.check(self.logger, config)
200
+ try:
201
+ check_result = self.source.check(self.logger, config)
202
+ except AirbyteTracedException as traced_exc:
203
+ yield traced_exc.as_airbyte_message()
204
+ # The platform uses the exit code to surface unexpected failures so we raise the exception if the failure type not a config error
205
+ # If the failure is not exceptional, we'll emit a failed connection status message and return
206
+ if traced_exc.failure_type != FailureType.config_error:
207
+ raise traced_exc
208
+ else:
209
+ yield AirbyteMessage(
210
+ type=Type.CONNECTION_STATUS,
211
+ connectionStatus=AirbyteConnectionStatus(
212
+ status=Status.FAILED, message=traced_exc.message
213
+ ),
214
+ )
215
+ return
140
216
  if check_result.status == Status.SUCCEEDED:
141
217
  self.logger.info("Check succeeded")
142
218
  else:
@@ -145,7 +221,9 @@ class AirbyteEntrypoint(object):
145
221
  yield from self._emit_queued_messages(self.source)
146
222
  yield AirbyteMessage(type=Type.CONNECTION_STATUS, connectionStatus=check_result)
147
223
 
148
- def discover(self, source_spec: ConnectorSpecification, config: TConfig) -> Iterable[AirbyteMessage]:
224
+ def discover(
225
+ self, source_spec: ConnectorSpecification, config: TConfig
226
+ ) -> Iterable[AirbyteMessage]:
149
227
  self.set_up_secret_filter(config, source_spec.connectionSpecification)
150
228
  if self.source.check_config_against_spec:
151
229
  self.validate_connection(source_spec, config)
@@ -155,32 +233,48 @@ class AirbyteEntrypoint(object):
155
233
  yield AirbyteMessage(type=Type.CATALOG, catalog=catalog)
156
234
 
157
235
  def read(
158
- self, source_spec: ConnectorSpecification, config: TConfig, catalog: Any, state: Union[list[Any], MutableMapping[str, Any]]
236
+ self, source_spec: ConnectorSpecification, config: TConfig, catalog: Any, state: list[Any]
159
237
  ) -> Iterable[AirbyteMessage]:
160
238
  self.set_up_secret_filter(config, source_spec.connectionSpecification)
161
239
  if self.source.check_config_against_spec:
162
240
  self.validate_connection(source_spec, config)
163
241
 
164
- stream_message_counter: DefaultDict[HashableStreamDescriptor, int] = defaultdict(int)
242
+ # The Airbyte protocol dictates that counts be expressed as float/double to better protect against integer overflows
243
+ stream_message_counter: DefaultDict[HashableStreamDescriptor, float] = defaultdict(float)
165
244
  for message in self.source.read(self.logger, config, catalog, state):
166
245
  yield self.handle_record_counts(message, stream_message_counter)
167
246
  for message in self._emit_queued_messages(self.source):
168
247
  yield self.handle_record_counts(message, stream_message_counter)
169
248
 
170
249
  @staticmethod
171
- def handle_record_counts(message: AirbyteMessage, stream_message_count: DefaultDict[HashableStreamDescriptor, int]) -> AirbyteMessage:
172
- if message.type == Type.RECORD:
173
- stream_message_count[message_utils.get_stream_descriptor(message)] += 1
174
-
175
- elif message.type == Type.STATE:
176
- stream_descriptor = message_utils.get_stream_descriptor(message)
177
-
178
- # Set record count from the counter onto the state message
179
- message.state.sourceStats = message.state.sourceStats or AirbyteStateStats()
180
- message.state.sourceStats.recordCount = stream_message_count.get(stream_descriptor, 0)
250
+ def handle_record_counts(
251
+ message: AirbyteMessage, stream_message_count: DefaultDict[HashableStreamDescriptor, float]
252
+ ) -> AirbyteMessage:
253
+ match message.type:
254
+ case Type.RECORD:
255
+ if message.record is None:
256
+ raise ValueError("Record message must have a record attribute")
257
+
258
+ stream_message_count[
259
+ HashableStreamDescriptor(
260
+ name=message.record.stream, # type: ignore[union-attr] # record has `stream`
261
+ namespace=message.record.namespace, # type: ignore[union-attr] # record has `namespace`
262
+ )
263
+ ] += 1.0
264
+ case Type.STATE:
265
+ if message.state is None:
266
+ raise ValueError("State message must have a state attribute")
267
+
268
+ stream_descriptor = message_utils.get_stream_descriptor(message)
269
+
270
+ # Set record count from the counter onto the state message
271
+ message.state.sourceStats = message.state.sourceStats or AirbyteStateStats() # type: ignore[union-attr] # state has `sourceStats`
272
+ message.state.sourceStats.recordCount = stream_message_count.get( # type: ignore[union-attr] # state has `sourceStats`
273
+ stream_descriptor, 0.0
274
+ )
181
275
 
182
- # Reset the counter
183
- stream_message_count[stream_descriptor] = 0
276
+ # Reset the counter
277
+ stream_message_count[stream_descriptor] = 0.0
184
278
  return message
185
279
 
186
280
  @staticmethod
@@ -198,8 +292,18 @@ class AirbyteEntrypoint(object):
198
292
  update_secrets(config_secrets)
199
293
 
200
294
  @staticmethod
201
- def airbyte_message_to_string(airbyte_message: AirbyteMessage) -> Any:
202
- return airbyte_message.json(exclude_unset=True)
295
+ def airbyte_message_to_string(airbyte_message: AirbyteMessage) -> str:
296
+ global _HAS_LOGGED_FOR_SERIALIZATION_ERROR
297
+ serialized_message = AirbyteMessageSerializer.dump(airbyte_message)
298
+ try:
299
+ return orjson.dumps(serialized_message).decode()
300
+ except Exception as exception:
301
+ if not _HAS_LOGGED_FOR_SERIALIZATION_ERROR:
302
+ logger.warning(
303
+ f"There was an error during the serialization of an AirbyteMessage: `{exception}`. This might impact the sync performances."
304
+ )
305
+ _HAS_LOGGED_FOR_SERIALIZATION_ERROR = True
306
+ return json.dumps(serialized_message)
203
307
 
204
308
  @classmethod
205
309
  def extract_state(cls, args: List[str]) -> Optional[Any]:
@@ -231,10 +335,13 @@ class AirbyteEntrypoint(object):
231
335
  def launch(source: Source, args: List[str]) -> None:
232
336
  source_entrypoint = AirbyteEntrypoint(source)
233
337
  parsed_args = source_entrypoint.parse_args(args)
338
+ # temporarily removes the PrintBuffer because we're seeing weird print behavior for concurrent syncs
339
+ # Refer to: https://github.com/airbytehq/oncall/issues/6235
340
+ # with PrintBuffer():
234
341
  for message in source_entrypoint.run(parsed_args):
235
342
  # simply printing is creating issues for concurrent CDK as Python uses different two instructions to print: one for the message and
236
343
  # the other for the break line. Adding `\n` to the message ensure that both are printed at the same time
237
- print(f"{message}\n", end="")
344
+ print(f"{message}\n", end="", flush=True)
238
345
 
239
346
 
240
347
  def _init_internal_request_filter() -> None:
@@ -254,7 +361,9 @@ def _init_internal_request_filter() -> None:
254
361
  )
255
362
 
256
363
  if not parsed_url.hostname:
257
- raise requests.exceptions.InvalidURL("Invalid URL specified: The endpoint that data is being requested from is not a valid URL")
364
+ raise requests.exceptions.InvalidURL(
365
+ "Invalid URL specified: The endpoint that data is being requested from is not a valid URL"
366
+ )
258
367
 
259
368
  try:
260
369
  is_private = _is_private_url(parsed_url.hostname, parsed_url.port) # type: ignore [arg-type]
@@ -5,12 +5,15 @@
5
5
  import logging
6
6
  import sys
7
7
  from types import TracebackType
8
- from typing import Any, Optional
8
+ from typing import Any, List, Mapping, Optional
9
9
 
10
+ from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets
10
11
  from airbyte_cdk.utils.traced_exception import AirbyteTracedException
11
12
 
12
13
 
13
- def assemble_uncaught_exception(exception_type: type[BaseException], exception_value: BaseException) -> AirbyteTracedException:
14
+ def assemble_uncaught_exception(
15
+ exception_type: type[BaseException], exception_value: BaseException
16
+ ) -> AirbyteTracedException:
14
17
  if issubclass(exception_type, AirbyteTracedException):
15
18
  return exception_value # type: ignore # validated as part of the previous line
16
19
  return AirbyteTracedException.from_exception(exception_value)
@@ -22,7 +25,11 @@ def init_uncaught_exception_handler(logger: logging.Logger) -> None:
22
25
  printed to the console without having secrets removed.
23
26
  """
24
27
 
25
- def hook_fn(exception_type: type[BaseException], exception_value: BaseException, traceback_: Optional[TracebackType]) -> Any:
28
+ def hook_fn(
29
+ exception_type: type[BaseException],
30
+ exception_value: BaseException,
31
+ traceback_: Optional[TracebackType],
32
+ ) -> Any:
26
33
  # For developer ergonomics, we want to see the stack trace in the logs when we do a ctrl-c
27
34
  if issubclass(exception_type, KeyboardInterrupt):
28
35
  sys.__excepthook__(exception_type, exception_value, traceback_)
@@ -36,3 +43,14 @@ def init_uncaught_exception_handler(logger: logging.Logger) -> None:
36
43
  traced_exc.emit_message()
37
44
 
38
45
  sys.excepthook = hook_fn
46
+
47
+
48
+ def generate_failed_streams_error_message(stream_failures: Mapping[str, List[Exception]]) -> str:
49
+ failures = "\n".join(
50
+ [
51
+ f"{stream}: {filter_secrets(exception.__repr__())}"
52
+ for stream, exceptions in stream_failures.items()
53
+ for exception in exceptions
54
+ ]
55
+ )
56
+ return f"During the sync, the following streams did not sync successfully: {failures}"
airbyte_cdk/logger.py CHANGED
@@ -5,12 +5,18 @@
5
5
  import json
6
6
  import logging
7
7
  import logging.config
8
- import traceback
9
- from typing import Tuple
8
+ from typing import Any, Callable, Mapping, Optional, Tuple
10
9
 
11
- from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage
10
+ import orjson
11
+
12
+ from airbyte_cdk.models import (
13
+ AirbyteLogMessage,
14
+ AirbyteMessage,
15
+ AirbyteMessageSerializer,
16
+ Level,
17
+ Type,
18
+ )
12
19
  from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets
13
- from deprecated import deprecated
14
20
 
15
21
  LOGGING_CONFIG = {
16
22
  "version": 1,
@@ -31,7 +37,7 @@ LOGGING_CONFIG = {
31
37
  }
32
38
 
33
39
 
34
- def init_logger(name: str = None):
40
+ def init_logger(name: Optional[str] = None) -> logging.Logger:
35
41
  """Initial set up of logger"""
36
42
  logger = logging.getLogger(name)
37
43
  logger.setLevel(logging.INFO)
@@ -39,33 +45,43 @@ def init_logger(name: str = None):
39
45
  return logger
40
46
 
41
47
 
48
+ def lazy_log(logger: logging.Logger, level: int, lazy_log_provider: Callable[[], str]) -> None:
49
+ """
50
+ This method ensure that the processing of the log message is only done if the logger is enabled for the log level.
51
+ """
52
+ if logger.isEnabledFor(level):
53
+ logger.log(level, lazy_log_provider())
54
+
55
+
42
56
  class AirbyteLogFormatter(logging.Formatter):
43
57
  """Output log records using AirbyteMessage"""
44
58
 
45
59
  # Transforming Python log levels to Airbyte protocol log levels
46
60
  level_mapping = {
47
- logging.FATAL: "FATAL",
48
- logging.ERROR: "ERROR",
49
- logging.WARNING: "WARN",
50
- logging.INFO: "INFO",
51
- logging.DEBUG: "DEBUG",
61
+ logging.FATAL: Level.FATAL,
62
+ logging.ERROR: Level.ERROR,
63
+ logging.WARNING: Level.WARN,
64
+ logging.INFO: Level.INFO,
65
+ logging.DEBUG: Level.DEBUG,
52
66
  }
53
67
 
54
68
  def format(self, record: logging.LogRecord) -> str:
55
69
  """Return a JSON representation of the log message"""
56
70
  airbyte_level = self.level_mapping.get(record.levelno, "INFO")
57
- if airbyte_level == "DEBUG":
71
+ if airbyte_level == Level.DEBUG:
58
72
  extras = self.extract_extra_args_from_record(record)
59
73
  debug_dict = {"type": "DEBUG", "message": record.getMessage(), "data": extras}
60
74
  return filter_secrets(json.dumps(debug_dict))
61
75
  else:
62
76
  message = super().format(record)
63
77
  message = filter_secrets(message)
64
- log_message = AirbyteMessage(type="LOG", log=AirbyteLogMessage(level=airbyte_level, message=message))
65
- return log_message.json(exclude_unset=True)
78
+ log_message = AirbyteMessage(
79
+ type=Type.LOG, log=AirbyteLogMessage(level=airbyte_level, message=message)
80
+ )
81
+ return orjson.dumps(AirbyteMessageSerializer.dump(log_message)).decode()
66
82
 
67
83
  @staticmethod
68
- def extract_extra_args_from_record(record: logging.LogRecord):
84
+ def extract_extra_args_from_record(record: logging.LogRecord) -> Mapping[str, Any]:
69
85
  """
70
86
  The python logger conflates default args with extra args. We use an empty log record and set operations
71
87
  to isolate fields passed to the log record via extra by the developer.
@@ -88,33 +104,3 @@ def log_by_prefix(msg: str, default_level: str) -> Tuple[int, str]:
88
104
  rendered_message = msg
89
105
 
90
106
  return log_level, rendered_message
91
-
92
-
93
- @deprecated(version="0.1.47", reason="Use logging.getLogger('airbyte') instead")
94
- class AirbyteLogger:
95
- def log(self, level, message):
96
- log_record = AirbyteLogMessage(level=level, message=message)
97
- log_message = AirbyteMessage(type="LOG", log=log_record)
98
- print(log_message.json(exclude_unset=True))
99
-
100
- def fatal(self, message):
101
- self.log("FATAL", message)
102
-
103
- def exception(self, message):
104
- message = f"{message}\n{traceback.format_exc()}"
105
- self.error(message)
106
-
107
- def error(self, message):
108
- self.log("ERROR", message)
109
-
110
- def warn(self, message):
111
- self.log("WARN", message)
112
-
113
- def info(self, message):
114
- self.log("INFO", message)
115
-
116
- def debug(self, message):
117
- self.log("DEBUG", message)
118
-
119
- def trace(self, message):
120
- self.log("TRACE", message)
@@ -21,10 +21,13 @@ from .airbyte_protocol import (
21
21
  AirbyteRecordMessage,
22
22
  AirbyteStateBlob,
23
23
  AirbyteStateMessage,
24
+ AirbyteStateStats,
24
25
  AirbyteStateType,
25
26
  AirbyteStream,
26
27
  AirbyteStreamState,
27
28
  AirbyteStreamStatus,
29
+ AirbyteStreamStatusReason,
30
+ AirbyteStreamStatusReasonType,
28
31
  AirbyteStreamStatusTraceMessage,
29
32
  AirbyteTraceMessage,
30
33
  AuthFlowType,
@@ -36,22 +39,30 @@ from .airbyte_protocol import (
36
39
  FailureType,
37
40
  Level,
38
41
  OAuthConfigSpecification,
42
+ OauthConnectorInputSpecification,
39
43
  OrchestratorType,
44
+ State,
40
45
  Status,
41
46
  StreamDescriptor,
42
47
  SyncMode,
43
48
  TraceType,
44
49
  Type,
45
50
  )
51
+ from .airbyte_protocol_serializers import (
52
+ AirbyteMessageSerializer,
53
+ AirbyteStateMessageSerializer,
54
+ AirbyteStreamStateSerializer,
55
+ ConfiguredAirbyteCatalogSerializer,
56
+ ConfiguredAirbyteStreamSerializer,
57
+ ConnectorSpecificationSerializer,
58
+ )
46
59
  from .well_known_types import (
47
60
  BinaryData,
48
61
  Boolean,
49
62
  Date,
50
63
  Integer,
51
- IntegerEnum,
52
64
  Model,
53
65
  Number,
54
- NumberEnum,
55
66
  String,
56
67
  TimestampWithoutTimezone,
57
68
  TimestampWithTimezone,
@@ -2,4 +2,89 @@
2
2
  # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
3
  #
4
4
 
5
- from airbyte_protocol.models import *
5
+ from dataclasses import InitVar, dataclass
6
+ from typing import Annotated, Any, Dict, List, Mapping, Optional, Union
7
+
8
+ from airbyte_protocol_dataclasses.models import * # noqa: F403 # Allow '*'
9
+ from serpyco_rs.metadata import Alias
10
+
11
+ from airbyte_cdk.models.file_transfer_record_message import AirbyteFileTransferRecordMessage
12
+
13
+ # ruff: noqa: F405 # ignore fuzzy import issues with 'import *'
14
+
15
+
16
+ @dataclass
17
+ class AirbyteStateBlob:
18
+ """
19
+ A dataclass that dynamically sets attributes based on provided keyword arguments and positional arguments.
20
+ Used to "mimic" pydantic Basemodel with ConfigDict(extra='allow') option.
21
+
22
+ The `AirbyteStateBlob` class allows for flexible instantiation by accepting any number of keyword arguments
23
+ and positional arguments. These are used to dynamically update the instance's attributes. This class is useful
24
+ in scenarios where the attributes of an object are not known until runtime and need to be set dynamically.
25
+
26
+ Attributes:
27
+ kwargs (InitVar[Mapping[str, Any]]): A dictionary of keyword arguments used to set attributes dynamically.
28
+
29
+ Methods:
30
+ __init__(*args: Any, **kwargs: Any) -> None:
31
+ Initializes the `AirbyteStateBlob` by setting attributes from the provided arguments.
32
+
33
+ __eq__(other: object) -> bool:
34
+ Checks equality between two `AirbyteStateBlob` instances based on their internal dictionaries.
35
+ Returns `False` if the other object is not an instance of `AirbyteStateBlob`.
36
+ """
37
+
38
+ kwargs: InitVar[Mapping[str, Any]]
39
+
40
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
41
+ # Set any attribute passed in through kwargs
42
+ for arg in args:
43
+ self.__dict__.update(arg)
44
+ for key, value in kwargs.items():
45
+ setattr(self, key, value)
46
+
47
+ def __eq__(self, other: object) -> bool:
48
+ return (
49
+ False
50
+ if not isinstance(other, AirbyteStateBlob)
51
+ else bool(self.__dict__ == other.__dict__)
52
+ )
53
+
54
+
55
+ # The following dataclasses have been redeclared to include the new version of AirbyteStateBlob
56
+ @dataclass
57
+ class AirbyteStreamState:
58
+ stream_descriptor: StreamDescriptor # type: ignore [name-defined]
59
+ stream_state: Optional[AirbyteStateBlob] = None
60
+
61
+
62
+ @dataclass
63
+ class AirbyteGlobalState:
64
+ stream_states: List[AirbyteStreamState]
65
+ shared_state: Optional[AirbyteStateBlob] = None
66
+
67
+
68
+ @dataclass
69
+ class AirbyteStateMessage:
70
+ type: Optional[AirbyteStateType] = None # type: ignore [name-defined]
71
+ stream: Optional[AirbyteStreamState] = None
72
+ global_: Annotated[AirbyteGlobalState | None, Alias("global")] = (
73
+ None # "global" is a reserved keyword in python ⇒ Alias is used for (de-)serialization
74
+ )
75
+ data: Optional[Dict[str, Any]] = None
76
+ sourceStats: Optional[AirbyteStateStats] = None # type: ignore [name-defined]
77
+ destinationStats: Optional[AirbyteStateStats] = None # type: ignore [name-defined]
78
+
79
+
80
+ @dataclass
81
+ class AirbyteMessage:
82
+ type: Type # type: ignore [name-defined]
83
+ log: Optional[AirbyteLogMessage] = None # type: ignore [name-defined]
84
+ spec: Optional[ConnectorSpecification] = None # type: ignore [name-defined]
85
+ connectionStatus: Optional[AirbyteConnectionStatus] = None # type: ignore [name-defined]
86
+ catalog: Optional[AirbyteCatalog] = None # type: ignore [name-defined]
87
+ record: Optional[Union[AirbyteFileTransferRecordMessage, AirbyteRecordMessage]] = None # type: ignore [name-defined]
88
+ state: Optional[AirbyteStateMessage] = None
89
+ trace: Optional[AirbyteTraceMessage] = None # type: ignore [name-defined]
90
+ control: Optional[AirbyteControlMessage] = None # type: ignore [name-defined]