airbyte-cdk 0.0.0.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. airbyte_cdk/__init__.py +358 -0
  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 +236 -0
  5. airbyte_cdk/cli/source_declarative_manifest/spec.json +17 -0
  6. airbyte_cdk/config_observation.py +104 -0
  7. airbyte_cdk/connector.py +123 -0
  8. airbyte_cdk/connector_builder/README.md +53 -0
  9. airbyte_cdk/connector_builder/__init__.py +3 -0
  10. airbyte_cdk/connector_builder/connector_builder_handler.py +121 -0
  11. airbyte_cdk/connector_builder/main.py +107 -0
  12. airbyte_cdk/connector_builder/models.py +73 -0
  13. airbyte_cdk/connector_builder/test_reader/__init__.py +7 -0
  14. airbyte_cdk/connector_builder/test_reader/helpers.py +689 -0
  15. airbyte_cdk/connector_builder/test_reader/message_grouper.py +173 -0
  16. airbyte_cdk/connector_builder/test_reader/reader.py +441 -0
  17. airbyte_cdk/connector_builder/test_reader/types.py +83 -0
  18. airbyte_cdk/destinations/__init__.py +8 -0
  19. airbyte_cdk/destinations/destination.py +154 -0
  20. airbyte_cdk/destinations/vector_db_based/README.md +37 -0
  21. airbyte_cdk/destinations/vector_db_based/__init__.py +38 -0
  22. airbyte_cdk/destinations/vector_db_based/config.py +298 -0
  23. airbyte_cdk/destinations/vector_db_based/document_processor.py +223 -0
  24. airbyte_cdk/destinations/vector_db_based/embedder.py +303 -0
  25. airbyte_cdk/destinations/vector_db_based/indexer.py +78 -0
  26. airbyte_cdk/destinations/vector_db_based/test_utils.py +63 -0
  27. airbyte_cdk/destinations/vector_db_based/utils.py +35 -0
  28. airbyte_cdk/destinations/vector_db_based/writer.py +104 -0
  29. airbyte_cdk/entrypoint.py +414 -0
  30. airbyte_cdk/exception_handler.py +56 -0
  31. airbyte_cdk/logger.py +109 -0
  32. airbyte_cdk/models/__init__.py +72 -0
  33. airbyte_cdk/models/airbyte_protocol.py +88 -0
  34. airbyte_cdk/models/airbyte_protocol_serializers.py +44 -0
  35. airbyte_cdk/models/well_known_types.py +5 -0
  36. airbyte_cdk/py.typed +0 -0
  37. airbyte_cdk/sources/__init__.py +26 -0
  38. airbyte_cdk/sources/abstract_source.py +326 -0
  39. airbyte_cdk/sources/concurrent_source/__init__.py +8 -0
  40. airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py +255 -0
  41. airbyte_cdk/sources/concurrent_source/concurrent_source.py +165 -0
  42. airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py +147 -0
  43. airbyte_cdk/sources/concurrent_source/partition_generation_completed_sentinel.py +24 -0
  44. airbyte_cdk/sources/concurrent_source/stream_thread_exception.py +25 -0
  45. airbyte_cdk/sources/concurrent_source/thread_pool_manager.py +115 -0
  46. airbyte_cdk/sources/config.py +27 -0
  47. airbyte_cdk/sources/connector_state_manager.py +161 -0
  48. airbyte_cdk/sources/declarative/__init__.py +3 -0
  49. airbyte_cdk/sources/declarative/async_job/__init__.py +0 -0
  50. airbyte_cdk/sources/declarative/async_job/job.py +52 -0
  51. airbyte_cdk/sources/declarative/async_job/job_orchestrator.py +525 -0
  52. airbyte_cdk/sources/declarative/async_job/job_tracker.py +79 -0
  53. airbyte_cdk/sources/declarative/async_job/repository.py +35 -0
  54. airbyte_cdk/sources/declarative/async_job/status.py +24 -0
  55. airbyte_cdk/sources/declarative/async_job/timer.py +39 -0
  56. airbyte_cdk/sources/declarative/auth/__init__.py +8 -0
  57. airbyte_cdk/sources/declarative/auth/declarative_authenticator.py +42 -0
  58. airbyte_cdk/sources/declarative/auth/jwt.py +197 -0
  59. airbyte_cdk/sources/declarative/auth/oauth.py +293 -0
  60. airbyte_cdk/sources/declarative/auth/selective_authenticator.py +45 -0
  61. airbyte_cdk/sources/declarative/auth/token.py +267 -0
  62. airbyte_cdk/sources/declarative/auth/token_provider.py +82 -0
  63. airbyte_cdk/sources/declarative/checks/__init__.py +24 -0
  64. airbyte_cdk/sources/declarative/checks/check_dynamic_stream.py +61 -0
  65. airbyte_cdk/sources/declarative/checks/check_stream.py +56 -0
  66. airbyte_cdk/sources/declarative/checks/connection_checker.py +35 -0
  67. airbyte_cdk/sources/declarative/concurrency_level/__init__.py +7 -0
  68. airbyte_cdk/sources/declarative/concurrency_level/concurrency_level.py +50 -0
  69. airbyte_cdk/sources/declarative/concurrent_declarative_source.py +526 -0
  70. airbyte_cdk/sources/declarative/datetime/__init__.py +3 -0
  71. airbyte_cdk/sources/declarative/datetime/datetime_parser.py +65 -0
  72. airbyte_cdk/sources/declarative/datetime/min_max_datetime.py +118 -0
  73. airbyte_cdk/sources/declarative/declarative_component_schema.yaml +3975 -0
  74. airbyte_cdk/sources/declarative/declarative_source.py +36 -0
  75. airbyte_cdk/sources/declarative/declarative_stream.py +241 -0
  76. airbyte_cdk/sources/declarative/decoders/__init__.py +33 -0
  77. airbyte_cdk/sources/declarative/decoders/composite_raw_decoder.py +218 -0
  78. airbyte_cdk/sources/declarative/decoders/decoder.py +32 -0
  79. airbyte_cdk/sources/declarative/decoders/decoder_parser.py +30 -0
  80. airbyte_cdk/sources/declarative/decoders/json_decoder.py +65 -0
  81. airbyte_cdk/sources/declarative/decoders/noop_decoder.py +21 -0
  82. airbyte_cdk/sources/declarative/decoders/pagination_decoder_decorator.py +39 -0
  83. airbyte_cdk/sources/declarative/decoders/xml_decoder.py +98 -0
  84. airbyte_cdk/sources/declarative/decoders/zipfile_decoder.py +56 -0
  85. airbyte_cdk/sources/declarative/exceptions.py +9 -0
  86. airbyte_cdk/sources/declarative/extractors/__init__.py +21 -0
  87. airbyte_cdk/sources/declarative/extractors/dpath_extractor.py +86 -0
  88. airbyte_cdk/sources/declarative/extractors/http_selector.py +37 -0
  89. airbyte_cdk/sources/declarative/extractors/record_extractor.py +27 -0
  90. airbyte_cdk/sources/declarative/extractors/record_filter.py +91 -0
  91. airbyte_cdk/sources/declarative/extractors/record_selector.py +170 -0
  92. airbyte_cdk/sources/declarative/extractors/response_to_file_extractor.py +176 -0
  93. airbyte_cdk/sources/declarative/extractors/type_transformer.py +55 -0
  94. airbyte_cdk/sources/declarative/incremental/__init__.py +37 -0
  95. airbyte_cdk/sources/declarative/incremental/concurrent_partition_cursor.py +497 -0
  96. airbyte_cdk/sources/declarative/incremental/datetime_based_cursor.py +459 -0
  97. airbyte_cdk/sources/declarative/incremental/declarative_cursor.py +13 -0
  98. airbyte_cdk/sources/declarative/incremental/global_substream_cursor.py +357 -0
  99. airbyte_cdk/sources/declarative/incremental/per_partition_cursor.py +380 -0
  100. airbyte_cdk/sources/declarative/incremental/per_partition_with_global.py +200 -0
  101. airbyte_cdk/sources/declarative/incremental/resumable_full_refresh_cursor.py +122 -0
  102. airbyte_cdk/sources/declarative/interpolation/__init__.py +9 -0
  103. airbyte_cdk/sources/declarative/interpolation/filters.py +139 -0
  104. airbyte_cdk/sources/declarative/interpolation/interpolated_boolean.py +66 -0
  105. airbyte_cdk/sources/declarative/interpolation/interpolated_mapping.py +56 -0
  106. airbyte_cdk/sources/declarative/interpolation/interpolated_nested_mapping.py +52 -0
  107. airbyte_cdk/sources/declarative/interpolation/interpolated_string.py +79 -0
  108. airbyte_cdk/sources/declarative/interpolation/interpolation.py +34 -0
  109. airbyte_cdk/sources/declarative/interpolation/jinja.py +161 -0
  110. airbyte_cdk/sources/declarative/interpolation/macros.py +191 -0
  111. airbyte_cdk/sources/declarative/manifest_declarative_source.py +421 -0
  112. airbyte_cdk/sources/declarative/migrations/__init__.py +0 -0
  113. airbyte_cdk/sources/declarative/migrations/legacy_to_per_partition_state_migration.py +98 -0
  114. airbyte_cdk/sources/declarative/migrations/state_migration.py +24 -0
  115. airbyte_cdk/sources/declarative/models/__init__.py +2 -0
  116. airbyte_cdk/sources/declarative/models/declarative_component_schema.py +2503 -0
  117. airbyte_cdk/sources/declarative/parsers/__init__.py +3 -0
  118. airbyte_cdk/sources/declarative/parsers/custom_code_compiler.py +157 -0
  119. airbyte_cdk/sources/declarative/parsers/custom_exceptions.py +21 -0
  120. airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py +172 -0
  121. airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py +213 -0
  122. airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +3407 -0
  123. airbyte_cdk/sources/declarative/partition_routers/__init__.py +29 -0
  124. airbyte_cdk/sources/declarative/partition_routers/async_job_partition_router.py +65 -0
  125. airbyte_cdk/sources/declarative/partition_routers/cartesian_product_stream_slicer.py +176 -0
  126. airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py +121 -0
  127. airbyte_cdk/sources/declarative/partition_routers/partition_router.py +62 -0
  128. airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py +63 -0
  129. airbyte_cdk/sources/declarative/partition_routers/substream_partition_router.py +437 -0
  130. airbyte_cdk/sources/declarative/requesters/README.md +56 -0
  131. airbyte_cdk/sources/declarative/requesters/__init__.py +9 -0
  132. airbyte_cdk/sources/declarative/requesters/error_handlers/__init__.py +25 -0
  133. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/__init__.py +23 -0
  134. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/constant_backoff_strategy.py +45 -0
  135. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/exponential_backoff_strategy.py +45 -0
  136. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/header_helper.py +41 -0
  137. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py +70 -0
  138. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py +77 -0
  139. airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategy.py +17 -0
  140. airbyte_cdk/sources/declarative/requesters/error_handlers/composite_error_handler.py +101 -0
  141. airbyte_cdk/sources/declarative/requesters/error_handlers/default_error_handler.py +147 -0
  142. airbyte_cdk/sources/declarative/requesters/error_handlers/default_http_response_filter.py +40 -0
  143. airbyte_cdk/sources/declarative/requesters/error_handlers/error_handler.py +17 -0
  144. airbyte_cdk/sources/declarative/requesters/error_handlers/http_response_filter.py +179 -0
  145. airbyte_cdk/sources/declarative/requesters/http_job_repository.py +350 -0
  146. airbyte_cdk/sources/declarative/requesters/http_requester.py +433 -0
  147. airbyte_cdk/sources/declarative/requesters/paginators/__init__.py +21 -0
  148. airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +327 -0
  149. airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py +76 -0
  150. airbyte_cdk/sources/declarative/requesters/paginators/paginator.py +65 -0
  151. airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py +25 -0
  152. airbyte_cdk/sources/declarative/requesters/paginators/strategies/cursor_pagination_strategy.py +98 -0
  153. airbyte_cdk/sources/declarative/requesters/paginators/strategies/offset_increment.py +102 -0
  154. airbyte_cdk/sources/declarative/requesters/paginators/strategies/page_increment.py +71 -0
  155. airbyte_cdk/sources/declarative/requesters/paginators/strategies/pagination_strategy.py +48 -0
  156. airbyte_cdk/sources/declarative/requesters/paginators/strategies/stop_condition.py +66 -0
  157. airbyte_cdk/sources/declarative/requesters/request_option.py +117 -0
  158. airbyte_cdk/sources/declarative/requesters/request_options/__init__.py +23 -0
  159. airbyte_cdk/sources/declarative/requesters/request_options/datetime_based_request_options_provider.py +92 -0
  160. airbyte_cdk/sources/declarative/requesters/request_options/default_request_options_provider.py +60 -0
  161. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py +59 -0
  162. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py +68 -0
  163. airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py +119 -0
  164. airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +79 -0
  165. airbyte_cdk/sources/declarative/requesters/request_path.py +15 -0
  166. airbyte_cdk/sources/declarative/requesters/requester.py +144 -0
  167. airbyte_cdk/sources/declarative/resolvers/__init__.py +41 -0
  168. airbyte_cdk/sources/declarative/resolvers/components_resolver.py +55 -0
  169. airbyte_cdk/sources/declarative/resolvers/config_components_resolver.py +136 -0
  170. airbyte_cdk/sources/declarative/resolvers/http_components_resolver.py +112 -0
  171. airbyte_cdk/sources/declarative/retrievers/__init__.py +19 -0
  172. airbyte_cdk/sources/declarative/retrievers/async_retriever.py +124 -0
  173. airbyte_cdk/sources/declarative/retrievers/file_uploader.py +89 -0
  174. airbyte_cdk/sources/declarative/retrievers/retriever.py +54 -0
  175. airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +702 -0
  176. airbyte_cdk/sources/declarative/schema/__init__.py +25 -0
  177. airbyte_cdk/sources/declarative/schema/default_schema_loader.py +47 -0
  178. airbyte_cdk/sources/declarative/schema/dynamic_schema_loader.py +285 -0
  179. airbyte_cdk/sources/declarative/schema/inline_schema_loader.py +19 -0
  180. airbyte_cdk/sources/declarative/schema/json_file_schema_loader.py +92 -0
  181. airbyte_cdk/sources/declarative/schema/schema_loader.py +17 -0
  182. airbyte_cdk/sources/declarative/spec/__init__.py +7 -0
  183. airbyte_cdk/sources/declarative/spec/spec.py +48 -0
  184. airbyte_cdk/sources/declarative/stream_slicers/__init__.py +7 -0
  185. airbyte_cdk/sources/declarative/stream_slicers/declarative_partition_generator.py +93 -0
  186. airbyte_cdk/sources/declarative/stream_slicers/stream_slicer.py +25 -0
  187. airbyte_cdk/sources/declarative/transformations/__init__.py +17 -0
  188. airbyte_cdk/sources/declarative/transformations/add_fields.py +146 -0
  189. airbyte_cdk/sources/declarative/transformations/dpath_flatten_fields.py +61 -0
  190. airbyte_cdk/sources/declarative/transformations/flatten_fields.py +52 -0
  191. airbyte_cdk/sources/declarative/transformations/keys_replace_transformation.py +61 -0
  192. airbyte_cdk/sources/declarative/transformations/keys_to_lower_transformation.py +22 -0
  193. airbyte_cdk/sources/declarative/transformations/keys_to_snake_transformation.py +68 -0
  194. airbyte_cdk/sources/declarative/transformations/remove_fields.py +75 -0
  195. airbyte_cdk/sources/declarative/transformations/transformation.py +37 -0
  196. airbyte_cdk/sources/declarative/types.py +25 -0
  197. airbyte_cdk/sources/declarative/yaml_declarative_source.py +67 -0
  198. airbyte_cdk/sources/file_based/README.md +152 -0
  199. airbyte_cdk/sources/file_based/__init__.py +24 -0
  200. airbyte_cdk/sources/file_based/availability_strategy/__init__.py +11 -0
  201. airbyte_cdk/sources/file_based/availability_strategy/abstract_file_based_availability_strategy.py +73 -0
  202. airbyte_cdk/sources/file_based/availability_strategy/default_file_based_availability_strategy.py +149 -0
  203. airbyte_cdk/sources/file_based/config/__init__.py +0 -0
  204. airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py +153 -0
  205. airbyte_cdk/sources/file_based/config/avro_format.py +25 -0
  206. airbyte_cdk/sources/file_based/config/csv_format.py +210 -0
  207. airbyte_cdk/sources/file_based/config/excel_format.py +18 -0
  208. airbyte_cdk/sources/file_based/config/file_based_stream_config.py +99 -0
  209. airbyte_cdk/sources/file_based/config/jsonl_format.py +18 -0
  210. airbyte_cdk/sources/file_based/config/parquet_format.py +25 -0
  211. airbyte_cdk/sources/file_based/config/unstructured_format.py +102 -0
  212. airbyte_cdk/sources/file_based/config/validate_config_transfer_modes.py +81 -0
  213. airbyte_cdk/sources/file_based/discovery_policy/__init__.py +8 -0
  214. airbyte_cdk/sources/file_based/discovery_policy/abstract_discovery_policy.py +21 -0
  215. airbyte_cdk/sources/file_based/discovery_policy/default_discovery_policy.py +33 -0
  216. airbyte_cdk/sources/file_based/exceptions.py +159 -0
  217. airbyte_cdk/sources/file_based/file_based_source.py +466 -0
  218. airbyte_cdk/sources/file_based/file_based_stream_permissions_reader.py +123 -0
  219. airbyte_cdk/sources/file_based/file_based_stream_reader.py +209 -0
  220. airbyte_cdk/sources/file_based/file_record_data.py +22 -0
  221. airbyte_cdk/sources/file_based/file_types/__init__.py +37 -0
  222. airbyte_cdk/sources/file_based/file_types/avro_parser.py +233 -0
  223. airbyte_cdk/sources/file_based/file_types/csv_parser.py +527 -0
  224. airbyte_cdk/sources/file_based/file_types/excel_parser.py +196 -0
  225. airbyte_cdk/sources/file_based/file_types/file_transfer.py +30 -0
  226. airbyte_cdk/sources/file_based/file_types/file_type_parser.py +86 -0
  227. airbyte_cdk/sources/file_based/file_types/jsonl_parser.py +145 -0
  228. airbyte_cdk/sources/file_based/file_types/parquet_parser.py +275 -0
  229. airbyte_cdk/sources/file_based/file_types/unstructured_parser.py +480 -0
  230. airbyte_cdk/sources/file_based/remote_file.py +18 -0
  231. airbyte_cdk/sources/file_based/schema_helpers.py +281 -0
  232. airbyte_cdk/sources/file_based/schema_validation_policies/__init__.py +17 -0
  233. airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py +20 -0
  234. airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py +52 -0
  235. airbyte_cdk/sources/file_based/stream/__init__.py +13 -0
  236. airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py +197 -0
  237. airbyte_cdk/sources/file_based/stream/concurrent/__init__.py +0 -0
  238. airbyte_cdk/sources/file_based/stream/concurrent/adapters.py +343 -0
  239. airbyte_cdk/sources/file_based/stream/concurrent/cursor/__init__.py +9 -0
  240. airbyte_cdk/sources/file_based/stream/concurrent/cursor/abstract_concurrent_file_based_cursor.py +59 -0
  241. airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_concurrent_cursor.py +313 -0
  242. airbyte_cdk/sources/file_based/stream/concurrent/cursor/file_based_final_state_cursor.py +83 -0
  243. airbyte_cdk/sources/file_based/stream/cursor/__init__.py +4 -0
  244. airbyte_cdk/sources/file_based/stream/cursor/abstract_file_based_cursor.py +66 -0
  245. airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py +149 -0
  246. airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +396 -0
  247. airbyte_cdk/sources/file_based/stream/identities_stream.py +49 -0
  248. airbyte_cdk/sources/file_based/stream/permissions_file_based_stream.py +92 -0
  249. airbyte_cdk/sources/file_based/types.py +10 -0
  250. airbyte_cdk/sources/http_config.py +10 -0
  251. airbyte_cdk/sources/http_logger.py +55 -0
  252. airbyte_cdk/sources/message/__init__.py +19 -0
  253. airbyte_cdk/sources/message/repository.py +137 -0
  254. airbyte_cdk/sources/source.py +95 -0
  255. airbyte_cdk/sources/specs/transfer_modes.py +26 -0
  256. airbyte_cdk/sources/streams/__init__.py +8 -0
  257. airbyte_cdk/sources/streams/availability_strategy.py +84 -0
  258. airbyte_cdk/sources/streams/call_rate.py +704 -0
  259. airbyte_cdk/sources/streams/checkpoint/__init__.py +26 -0
  260. airbyte_cdk/sources/streams/checkpoint/checkpoint_reader.py +335 -0
  261. airbyte_cdk/sources/streams/checkpoint/cursor.py +77 -0
  262. airbyte_cdk/sources/streams/checkpoint/per_partition_key_serializer.py +22 -0
  263. airbyte_cdk/sources/streams/checkpoint/resumable_full_refresh_cursor.py +51 -0
  264. airbyte_cdk/sources/streams/checkpoint/substream_resumable_full_refresh_cursor.py +110 -0
  265. airbyte_cdk/sources/streams/concurrent/README.md +7 -0
  266. airbyte_cdk/sources/streams/concurrent/__init__.py +3 -0
  267. airbyte_cdk/sources/streams/concurrent/abstract_stream.py +96 -0
  268. airbyte_cdk/sources/streams/concurrent/abstract_stream_facade.py +37 -0
  269. airbyte_cdk/sources/streams/concurrent/adapters.py +397 -0
  270. airbyte_cdk/sources/streams/concurrent/availability_strategy.py +94 -0
  271. airbyte_cdk/sources/streams/concurrent/clamping.py +99 -0
  272. airbyte_cdk/sources/streams/concurrent/cursor.py +481 -0
  273. airbyte_cdk/sources/streams/concurrent/cursor_types.py +32 -0
  274. airbyte_cdk/sources/streams/concurrent/default_stream.py +102 -0
  275. airbyte_cdk/sources/streams/concurrent/exceptions.py +18 -0
  276. airbyte_cdk/sources/streams/concurrent/helpers.py +42 -0
  277. airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py +64 -0
  278. airbyte_cdk/sources/streams/concurrent/partition_reader.py +45 -0
  279. airbyte_cdk/sources/streams/concurrent/partitions/__init__.py +3 -0
  280. airbyte_cdk/sources/streams/concurrent/partitions/partition.py +48 -0
  281. airbyte_cdk/sources/streams/concurrent/partitions/partition_generator.py +18 -0
  282. airbyte_cdk/sources/streams/concurrent/partitions/stream_slicer.py +21 -0
  283. airbyte_cdk/sources/streams/concurrent/partitions/types.py +38 -0
  284. airbyte_cdk/sources/streams/concurrent/state_converters/__init__.py +0 -0
  285. airbyte_cdk/sources/streams/concurrent/state_converters/abstract_stream_state_converter.py +182 -0
  286. airbyte_cdk/sources/streams/concurrent/state_converters/datetime_stream_state_converter.py +223 -0
  287. airbyte_cdk/sources/streams/concurrent/state_converters/incrementing_count_stream_state_converter.py +92 -0
  288. airbyte_cdk/sources/streams/core.py +703 -0
  289. airbyte_cdk/sources/streams/http/__init__.py +10 -0
  290. airbyte_cdk/sources/streams/http/availability_strategy.py +54 -0
  291. airbyte_cdk/sources/streams/http/error_handlers/__init__.py +22 -0
  292. airbyte_cdk/sources/streams/http/error_handlers/backoff_strategy.py +28 -0
  293. airbyte_cdk/sources/streams/http/error_handlers/default_backoff_strategy.py +17 -0
  294. airbyte_cdk/sources/streams/http/error_handlers/default_error_mapping.py +86 -0
  295. airbyte_cdk/sources/streams/http/error_handlers/error_handler.py +42 -0
  296. airbyte_cdk/sources/streams/http/error_handlers/error_message_parser.py +19 -0
  297. airbyte_cdk/sources/streams/http/error_handlers/http_status_error_handler.py +110 -0
  298. airbyte_cdk/sources/streams/http/error_handlers/json_error_message_parser.py +52 -0
  299. airbyte_cdk/sources/streams/http/error_handlers/response_models.py +65 -0
  300. airbyte_cdk/sources/streams/http/exceptions.py +61 -0
  301. airbyte_cdk/sources/streams/http/http.py +673 -0
  302. airbyte_cdk/sources/streams/http/http_client.py +531 -0
  303. airbyte_cdk/sources/streams/http/rate_limiting.py +158 -0
  304. airbyte_cdk/sources/streams/http/requests_native_auth/__init__.py +14 -0
  305. airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +479 -0
  306. airbyte_cdk/sources/streams/http/requests_native_auth/abstract_token.py +34 -0
  307. airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +436 -0
  308. airbyte_cdk/sources/streams/http/requests_native_auth/token.py +83 -0
  309. airbyte_cdk/sources/streams/permissions/identities_stream.py +75 -0
  310. airbyte_cdk/sources/streams/utils/__init__.py +3 -0
  311. airbyte_cdk/sources/types.py +169 -0
  312. airbyte_cdk/sources/utils/__init__.py +7 -0
  313. airbyte_cdk/sources/utils/casing.py +12 -0
  314. airbyte_cdk/sources/utils/files_directory.py +15 -0
  315. airbyte_cdk/sources/utils/record_helper.py +53 -0
  316. airbyte_cdk/sources/utils/schema_helpers.py +230 -0
  317. airbyte_cdk/sources/utils/slice_logger.py +57 -0
  318. airbyte_cdk/sources/utils/transform.py +277 -0
  319. airbyte_cdk/sources/utils/types.py +7 -0
  320. airbyte_cdk/sql/__init__.py +0 -0
  321. airbyte_cdk/sql/_util/__init__.py +0 -0
  322. airbyte_cdk/sql/_util/hashing.py +34 -0
  323. airbyte_cdk/sql/_util/name_normalizers.py +92 -0
  324. airbyte_cdk/sql/constants.py +32 -0
  325. airbyte_cdk/sql/exceptions.py +235 -0
  326. airbyte_cdk/sql/secrets.py +123 -0
  327. airbyte_cdk/sql/shared/__init__.py +15 -0
  328. airbyte_cdk/sql/shared/catalog_providers.py +145 -0
  329. airbyte_cdk/sql/shared/sql_processor.py +786 -0
  330. airbyte_cdk/sql/types.py +160 -0
  331. airbyte_cdk/test/__init__.py +7 -0
  332. airbyte_cdk/test/catalog_builder.py +81 -0
  333. airbyte_cdk/test/entrypoint_wrapper.py +250 -0
  334. airbyte_cdk/test/mock_http/__init__.py +6 -0
  335. airbyte_cdk/test/mock_http/matcher.py +41 -0
  336. airbyte_cdk/test/mock_http/mocker.py +185 -0
  337. airbyte_cdk/test/mock_http/request.py +103 -0
  338. airbyte_cdk/test/mock_http/response.py +28 -0
  339. airbyte_cdk/test/mock_http/response_builder.py +237 -0
  340. airbyte_cdk/test/state_builder.py +33 -0
  341. airbyte_cdk/test/utils/__init__.py +1 -0
  342. airbyte_cdk/test/utils/data.py +24 -0
  343. airbyte_cdk/test/utils/http_mocking.py +16 -0
  344. airbyte_cdk/test/utils/manifest_only_fixtures.py +59 -0
  345. airbyte_cdk/test/utils/reading.py +26 -0
  346. airbyte_cdk/utils/__init__.py +10 -0
  347. airbyte_cdk/utils/airbyte_secrets_utils.py +80 -0
  348. airbyte_cdk/utils/analytics_message.py +25 -0
  349. airbyte_cdk/utils/constants.py +5 -0
  350. airbyte_cdk/utils/datetime_format_inferrer.py +94 -0
  351. airbyte_cdk/utils/datetime_helpers.py +499 -0
  352. airbyte_cdk/utils/event_timing.py +85 -0
  353. airbyte_cdk/utils/is_cloud_environment.py +18 -0
  354. airbyte_cdk/utils/mapping_helpers.py +162 -0
  355. airbyte_cdk/utils/message_utils.py +26 -0
  356. airbyte_cdk/utils/oneof_option_config.py +33 -0
  357. airbyte_cdk/utils/print_buffer.py +75 -0
  358. airbyte_cdk/utils/schema_inferrer.py +270 -0
  359. airbyte_cdk/utils/slice_hasher.py +37 -0
  360. airbyte_cdk/utils/spec_schema_transformations.py +26 -0
  361. airbyte_cdk/utils/stream_status_utils.py +43 -0
  362. airbyte_cdk/utils/traced_exception.py +145 -0
  363. airbyte_cdk-0.0.0.dev0.dist-info/LICENSE.txt +19 -0
  364. airbyte_cdk-0.0.0.dev0.dist-info/LICENSE_SHORT +1 -0
  365. airbyte_cdk-0.0.0.dev0.dist-info/METADATA +111 -0
  366. airbyte_cdk-0.0.0.dev0.dist-info/RECORD +368 -0
  367. airbyte_cdk-0.0.0.dev0.dist-info/WHEEL +4 -0
  368. airbyte_cdk-0.0.0.dev0.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,29 @@
1
+ #
2
+ # Copyright (c) 2022 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from airbyte_cdk.sources.declarative.partition_routers.async_job_partition_router import (
6
+ AsyncJobPartitionRouter,
7
+ )
8
+ from airbyte_cdk.sources.declarative.partition_routers.cartesian_product_stream_slicer import (
9
+ CartesianProductStreamSlicer,
10
+ )
11
+ from airbyte_cdk.sources.declarative.partition_routers.list_partition_router import (
12
+ ListPartitionRouter,
13
+ )
14
+ from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter
15
+ from airbyte_cdk.sources.declarative.partition_routers.single_partition_router import (
16
+ SinglePartitionRouter,
17
+ )
18
+ from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import (
19
+ SubstreamPartitionRouter,
20
+ )
21
+
22
+ __all__ = [
23
+ "AsyncJobPartitionRouter",
24
+ "CartesianProductStreamSlicer",
25
+ "ListPartitionRouter",
26
+ "SinglePartitionRouter",
27
+ "SubstreamPartitionRouter",
28
+ "PartitionRouter",
29
+ ]
@@ -0,0 +1,65 @@
1
+ # Copyright (c) 2024 Airbyte, Inc., all rights reserved.
2
+
3
+ from dataclasses import InitVar, dataclass, field
4
+ from typing import Any, Callable, Iterable, Mapping, Optional
5
+
6
+ from airbyte_cdk.models import FailureType
7
+ from airbyte_cdk.sources.declarative.async_job.job import AsyncJob
8
+ from airbyte_cdk.sources.declarative.async_job.job_orchestrator import (
9
+ AsyncJobOrchestrator,
10
+ )
11
+ from airbyte_cdk.sources.declarative.partition_routers.single_partition_router import (
12
+ SinglePartitionRouter,
13
+ )
14
+ from airbyte_cdk.sources.streams.concurrent.partitions.stream_slicer import StreamSlicer
15
+ from airbyte_cdk.sources.types import Config, StreamSlice
16
+ from airbyte_cdk.utils.traced_exception import AirbyteTracedException
17
+
18
+
19
+ @dataclass
20
+ class AsyncJobPartitionRouter(StreamSlicer):
21
+ """
22
+ Partition router that creates async jobs in a source API, periodically polls for job
23
+ completion, and supplies the completed job URL locations as stream slices so that
24
+ records can be extracted.
25
+ """
26
+
27
+ config: Config
28
+ parameters: InitVar[Mapping[str, Any]]
29
+ job_orchestrator_factory: Callable[[Iterable[StreamSlice]], AsyncJobOrchestrator]
30
+ stream_slicer: StreamSlicer = field(
31
+ default_factory=lambda: SinglePartitionRouter(parameters={})
32
+ )
33
+
34
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
35
+ self._job_orchestrator_factory = self.job_orchestrator_factory
36
+ self._job_orchestrator: Optional[AsyncJobOrchestrator] = None
37
+ self._parameters = parameters
38
+
39
+ def stream_slices(self) -> Iterable[StreamSlice]:
40
+ slices = self.stream_slicer.stream_slices()
41
+ self._job_orchestrator = self._job_orchestrator_factory(slices)
42
+
43
+ for completed_partition in self._job_orchestrator.create_and_get_completed_partitions():
44
+ yield StreamSlice(
45
+ partition=dict(completed_partition.stream_slice.partition),
46
+ cursor_slice=completed_partition.stream_slice.cursor_slice,
47
+ extra_fields={"jobs": list(completed_partition.jobs)},
48
+ )
49
+
50
+ def fetch_records(self, async_jobs: Iterable[AsyncJob]) -> Iterable[Mapping[str, Any]]:
51
+ """
52
+ This method of fetching records extends beyond what a PartitionRouter/StreamSlicer should
53
+ be responsible for. However, this was added in because the JobOrchestrator is required to
54
+ retrieve records. And without defining fetch_records() on this class, we're stuck with either
55
+ passing the JobOrchestrator to the AsyncRetriever or storing it on multiple classes.
56
+ """
57
+
58
+ if not self._job_orchestrator:
59
+ raise AirbyteTracedException(
60
+ message="Invalid state within AsyncJobRetriever. Please contact Airbyte Support",
61
+ internal_message="AsyncPartitionRepository is expected to be accessed only after `stream_slices`",
62
+ failure_type=FailureType.system_error,
63
+ )
64
+
65
+ return self._job_orchestrator.fetch_records(async_jobs=async_jobs)
@@ -0,0 +1,176 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ import itertools
6
+ import logging
7
+ from collections import ChainMap
8
+ from collections.abc import Callable
9
+ from dataclasses import InitVar, dataclass
10
+ from typing import Any, Iterable, List, Mapping, Optional
11
+
12
+ from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter
13
+ from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import (
14
+ SubstreamPartitionRouter,
15
+ )
16
+ from airbyte_cdk.sources.types import StreamSlice, StreamState
17
+
18
+
19
+ def check_for_substream_in_slicers(
20
+ slicers: Iterable[PartitionRouter], log_warning: Callable[[str], None]
21
+ ) -> None:
22
+ """
23
+ Recursively checks for the presence of SubstreamPartitionRouter within slicers.
24
+ Logs a warning if a SubstreamPartitionRouter is found within a CartesianProductStreamSlicer.
25
+
26
+ Args:
27
+ slicers (Iterable[PartitionRouter]): The list of slicers to check.
28
+ log_warning (Callable): Logging function to record warnings.
29
+ """
30
+ for slicer in slicers:
31
+ if isinstance(slicer, SubstreamPartitionRouter):
32
+ log_warning("Parent state handling is not supported for CartesianProductStreamSlicer.")
33
+ return
34
+ elif isinstance(slicer, CartesianProductStreamSlicer):
35
+ # Recursively check sub-slicers within CartesianProductStreamSlicer
36
+ check_for_substream_in_slicers(slicer.stream_slicers, log_warning)
37
+
38
+
39
+ @dataclass
40
+ class CartesianProductStreamSlicer(PartitionRouter):
41
+ """
42
+ Stream slicers that iterates over the cartesian product of input stream slicers
43
+ Given 2 stream slicers with the following slices:
44
+ A: [{"i": 0}, {"i": 1}, {"i": 2}]
45
+ B: [{"s": "hello"}, {"s": "world"}]
46
+ the resulting stream slices are
47
+ [
48
+ {"i": 0, "s": "hello"},
49
+ {"i": 0, "s": "world"},
50
+ {"i": 1, "s": "hello"},
51
+ {"i": 1, "s": "world"},
52
+ {"i": 2, "s": "hello"},
53
+ {"i": 2, "s": "world"},
54
+ ]
55
+
56
+ Attributes:
57
+ stream_slicers (List[PartitionRouter]): Underlying stream slicers. The RequestOptions (e.g: Request headers, parameters, etc..) returned by this slicer are the combination of the RequestOptions of its input slicers. If there are conflicts e.g: two slicers define the same header or request param, the conflict is resolved by taking the value from the first slicer, where ordering is determined by the order in which slicers were input to this composite slicer.
58
+ """
59
+
60
+ stream_slicers: List[PartitionRouter]
61
+ parameters: InitVar[Mapping[str, Any]]
62
+
63
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
64
+ check_for_substream_in_slicers(self.stream_slicers, self.logger.warning)
65
+
66
+ def get_request_params(
67
+ self,
68
+ *,
69
+ stream_state: Optional[StreamState] = None,
70
+ stream_slice: Optional[StreamSlice] = None,
71
+ next_page_token: Optional[Mapping[str, Any]] = None,
72
+ ) -> Mapping[str, Any]:
73
+ return dict(
74
+ ChainMap(
75
+ *[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
76
+ s.get_request_params(
77
+ stream_state=stream_state,
78
+ stream_slice=stream_slice,
79
+ next_page_token=next_page_token,
80
+ )
81
+ for s in self.stream_slicers
82
+ ]
83
+ )
84
+ )
85
+
86
+ def get_request_headers(
87
+ self,
88
+ *,
89
+ stream_state: Optional[StreamState] = None,
90
+ stream_slice: Optional[StreamSlice] = None,
91
+ next_page_token: Optional[Mapping[str, Any]] = None,
92
+ ) -> Mapping[str, Any]:
93
+ return dict(
94
+ ChainMap(
95
+ *[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
96
+ s.get_request_headers(
97
+ stream_state=stream_state,
98
+ stream_slice=stream_slice,
99
+ next_page_token=next_page_token,
100
+ )
101
+ for s in self.stream_slicers
102
+ ]
103
+ )
104
+ )
105
+
106
+ def get_request_body_data(
107
+ self,
108
+ *,
109
+ stream_state: Optional[StreamState] = None,
110
+ stream_slice: Optional[StreamSlice] = None,
111
+ next_page_token: Optional[Mapping[str, Any]] = None,
112
+ ) -> Mapping[str, Any]:
113
+ return dict(
114
+ ChainMap(
115
+ *[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
116
+ s.get_request_body_data(
117
+ stream_state=stream_state,
118
+ stream_slice=stream_slice,
119
+ next_page_token=next_page_token,
120
+ )
121
+ for s in self.stream_slicers
122
+ ]
123
+ )
124
+ )
125
+
126
+ def get_request_body_json(
127
+ self,
128
+ *,
129
+ stream_state: Optional[StreamState] = None,
130
+ stream_slice: Optional[StreamSlice] = None,
131
+ next_page_token: Optional[Mapping[str, Any]] = None,
132
+ ) -> Mapping[str, Any]:
133
+ return dict(
134
+ ChainMap(
135
+ *[ # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
136
+ s.get_request_body_json(
137
+ stream_state=stream_state,
138
+ stream_slice=stream_slice,
139
+ next_page_token=next_page_token,
140
+ )
141
+ for s in self.stream_slicers
142
+ ]
143
+ )
144
+ )
145
+
146
+ def stream_slices(self) -> Iterable[StreamSlice]:
147
+ sub_slices = (s.stream_slices() for s in self.stream_slicers)
148
+ product = itertools.product(*sub_slices)
149
+ for stream_slice_tuple in product:
150
+ partition = dict(ChainMap(*[s.partition for s in stream_slice_tuple])) # type: ignore # ChainMap expects a MutableMapping[Never, Never] for reasons
151
+ cursor_slices = [s.cursor_slice for s in stream_slice_tuple if s.cursor_slice]
152
+ if len(cursor_slices) > 1:
153
+ raise ValueError(
154
+ f"There should only be a single cursor slice. Found {cursor_slices}"
155
+ )
156
+ if cursor_slices:
157
+ cursor_slice = cursor_slices[0]
158
+ else:
159
+ cursor_slice = {}
160
+ yield StreamSlice(partition=partition, cursor_slice=cursor_slice)
161
+
162
+ def set_initial_state(self, stream_state: StreamState) -> None:
163
+ """
164
+ Parent stream states are not supported for cartesian product stream slicer
165
+ """
166
+ pass
167
+
168
+ def get_stream_state(self) -> Optional[Mapping[str, StreamState]]:
169
+ """
170
+ Parent stream states are not supported for cartesian product stream slicer
171
+ """
172
+ pass
173
+
174
+ @property
175
+ def logger(self) -> logging.Logger:
176
+ return logging.getLogger("airbyte.CartesianProductStreamSlicer")
@@ -0,0 +1,121 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass
6
+ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union
7
+
8
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
9
+ from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter
10
+ from airbyte_cdk.sources.declarative.requesters.request_option import (
11
+ RequestOption,
12
+ RequestOptionType,
13
+ )
14
+ from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
15
+
16
+
17
+ @dataclass
18
+ class ListPartitionRouter(PartitionRouter):
19
+ """
20
+ Partition router that iterates over the values of a list
21
+ If values is a string, then evaluate it as literal and assert the resulting literal is a list
22
+
23
+ Attributes:
24
+ values (Union[str, List[str]]): The values to iterate over
25
+ cursor_field (Union[InterpolatedString, str]): The name of the cursor field
26
+ config (Config): The user-provided configuration as specified by the source's spec
27
+ request_option (Optional[RequestOption]): The request option to configure the HTTP request
28
+ """
29
+
30
+ values: Union[str, List[str]]
31
+ cursor_field: Union[InterpolatedString, str]
32
+ config: Config
33
+ parameters: InitVar[Mapping[str, Any]]
34
+ request_option: Optional[RequestOption] = None
35
+
36
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
37
+ if isinstance(self.values, str):
38
+ self.values = InterpolatedString.create(self.values, parameters=parameters).eval(
39
+ self.config
40
+ )
41
+ self._cursor_field = (
42
+ InterpolatedString(string=self.cursor_field, parameters=parameters)
43
+ if isinstance(self.cursor_field, str)
44
+ else self.cursor_field
45
+ )
46
+
47
+ self._cursor = None
48
+
49
+ def get_request_params(
50
+ self,
51
+ stream_state: Optional[StreamState] = None,
52
+ stream_slice: Optional[StreamSlice] = None,
53
+ next_page_token: Optional[Mapping[str, Any]] = None,
54
+ ) -> Mapping[str, Any]:
55
+ # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response
56
+ return self._get_request_option(RequestOptionType.request_parameter, stream_slice)
57
+
58
+ def get_request_headers(
59
+ self,
60
+ stream_state: Optional[StreamState] = None,
61
+ stream_slice: Optional[StreamSlice] = None,
62
+ next_page_token: Optional[Mapping[str, Any]] = None,
63
+ ) -> Mapping[str, Any]:
64
+ # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response
65
+ return self._get_request_option(RequestOptionType.header, stream_slice)
66
+
67
+ def get_request_body_data(
68
+ self,
69
+ stream_state: Optional[StreamState] = None,
70
+ stream_slice: Optional[StreamSlice] = None,
71
+ next_page_token: Optional[Mapping[str, Any]] = None,
72
+ ) -> Mapping[str, Any]:
73
+ # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response
74
+ return self._get_request_option(RequestOptionType.body_data, stream_slice)
75
+
76
+ def get_request_body_json(
77
+ self,
78
+ stream_state: Optional[StreamState] = None,
79
+ stream_slice: Optional[StreamSlice] = None,
80
+ next_page_token: Optional[Mapping[str, Any]] = None,
81
+ ) -> Mapping[str, Any]:
82
+ # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response
83
+ return self._get_request_option(RequestOptionType.body_json, stream_slice)
84
+
85
+ def stream_slices(self) -> Iterable[StreamSlice]:
86
+ return [
87
+ StreamSlice(
88
+ partition={self._cursor_field.eval(self.config): slice_value}, cursor_slice={}
89
+ )
90
+ for slice_value in self.values
91
+ ]
92
+
93
+ def _get_request_option(
94
+ self, request_option_type: RequestOptionType, stream_slice: Optional[StreamSlice]
95
+ ) -> Mapping[str, Any]:
96
+ if (
97
+ self.request_option
98
+ and self.request_option.inject_into == request_option_type
99
+ and stream_slice
100
+ ):
101
+ slice_value = stream_slice.get(self._cursor_field.eval(self.config))
102
+ if slice_value:
103
+ options: MutableMapping[str, Any] = {}
104
+ self.request_option.inject_into_request(options, slice_value, self.config)
105
+ return options
106
+ else:
107
+ return {}
108
+ else:
109
+ return {}
110
+
111
+ def set_initial_state(self, stream_state: StreamState) -> None:
112
+ """
113
+ ListPartitionRouter doesn't have parent streams
114
+ """
115
+ pass
116
+
117
+ def get_stream_state(self) -> Optional[Mapping[str, StreamState]]:
118
+ """
119
+ ListPartitionRouter doesn't have parent streams
120
+ """
121
+ pass
@@ -0,0 +1,62 @@
1
+ #
2
+ # Copyright (c) 2024 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from abc import abstractmethod
6
+ from dataclasses import dataclass
7
+ from typing import Mapping, Optional
8
+
9
+ from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer
10
+ from airbyte_cdk.sources.types import StreamState
11
+
12
+
13
+ @dataclass
14
+ class PartitionRouter(StreamSlicer):
15
+ """
16
+ Base class for partition routers.
17
+ Methods:
18
+ set_parent_state(stream_state): Set the state of the parent streams.
19
+ get_parent_state(): Get the state of the parent streams.
20
+ """
21
+
22
+ @abstractmethod
23
+ def set_initial_state(self, stream_state: StreamState) -> None:
24
+ """
25
+ Set the state of the parent streams.
26
+
27
+ This method should only be implemented if the slicer is based on some parent stream and needs to read this stream
28
+ incrementally using the state.
29
+
30
+ Args:
31
+ stream_state (StreamState): The state of the streams to be set. The expected format is a dictionary that includes
32
+ 'parent_state' which is a dictionary of parent state names to their corresponding state.
33
+ Example:
34
+ {
35
+ "parent_state": {
36
+ "parent_stream_name_1": { ... },
37
+ "parent_stream_name_2": { ... },
38
+ ...
39
+ }
40
+ }
41
+ """
42
+
43
+ @abstractmethod
44
+ def get_stream_state(self) -> Optional[Mapping[str, StreamState]]:
45
+ """
46
+ Get the state of the parent streams.
47
+
48
+ This method should only be implemented if the slicer is based on some parent stream and needs to read this stream
49
+ incrementally using the state.
50
+
51
+ Returns:
52
+ Optional[Mapping[str, StreamState]]: The current state of the parent streams in a dictionary format.
53
+ The returned format will be:
54
+ {
55
+ "parent_stream_name1": {
56
+ "last_updated": "2023-05-27T00:00:00Z"
57
+ },
58
+ "parent_stream_name2": {
59
+ "last_updated": "2023-05-27T00:00:00Z"
60
+ }
61
+ }
62
+ """
@@ -0,0 +1,63 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass
6
+ from typing import Any, Iterable, Mapping, Optional
7
+
8
+ from airbyte_cdk.sources.declarative.partition_routers.partition_router import PartitionRouter
9
+ from airbyte_cdk.sources.types import StreamSlice, StreamState
10
+
11
+
12
+ @dataclass
13
+ class SinglePartitionRouter(PartitionRouter):
14
+ """Partition router returning only a stream slice"""
15
+
16
+ parameters: InitVar[Mapping[str, Any]]
17
+
18
+ def get_request_params(
19
+ self,
20
+ stream_state: Optional[StreamState] = None,
21
+ stream_slice: Optional[StreamSlice] = None,
22
+ next_page_token: Optional[Mapping[str, Any]] = None,
23
+ ) -> Mapping[str, Any]:
24
+ return {}
25
+
26
+ def get_request_headers(
27
+ self,
28
+ stream_state: Optional[StreamState] = None,
29
+ stream_slice: Optional[StreamSlice] = None,
30
+ next_page_token: Optional[Mapping[str, Any]] = None,
31
+ ) -> Mapping[str, Any]:
32
+ return {}
33
+
34
+ def get_request_body_data(
35
+ self,
36
+ stream_state: Optional[StreamState] = None,
37
+ stream_slice: Optional[StreamSlice] = None,
38
+ next_page_token: Optional[Mapping[str, Any]] = None,
39
+ ) -> Mapping[str, Any]:
40
+ return {}
41
+
42
+ def get_request_body_json(
43
+ self,
44
+ stream_state: Optional[StreamState] = None,
45
+ stream_slice: Optional[StreamSlice] = None,
46
+ next_page_token: Optional[Mapping[str, Any]] = None,
47
+ ) -> Mapping[str, Any]:
48
+ return {}
49
+
50
+ def stream_slices(self) -> Iterable[StreamSlice]:
51
+ yield StreamSlice(partition={}, cursor_slice={})
52
+
53
+ def set_initial_state(self, stream_state: StreamState) -> None:
54
+ """
55
+ SinglePartitionRouter doesn't have parent streams
56
+ """
57
+ pass
58
+
59
+ def get_stream_state(self) -> Optional[Mapping[str, StreamState]]:
60
+ """
61
+ SinglePartitionRouter doesn't have parent streams
62
+ """
63
+ pass