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,71 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass
6
+ from typing import Any, Mapping, Optional, Union
7
+
8
+ import requests
9
+
10
+ from airbyte_cdk.sources.declarative.interpolation import InterpolatedString
11
+ from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
12
+ PaginationStrategy,
13
+ )
14
+ from airbyte_cdk.sources.types import Config, Record
15
+
16
+
17
+ @dataclass
18
+ class PageIncrement(PaginationStrategy):
19
+ """
20
+ Pagination strategy that returns the number of pages reads so far and returns it as the next page token
21
+
22
+ Attributes:
23
+ page_size (int): the number of records to request
24
+ start_from_page (int): number of the initial page
25
+ """
26
+
27
+ config: Config
28
+ page_size: Optional[Union[str, int]]
29
+ parameters: InitVar[Mapping[str, Any]]
30
+ start_from_page: int = 0
31
+ inject_on_first_request: bool = False
32
+
33
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
34
+ if isinstance(self.page_size, int) or (self.page_size is None):
35
+ self._page_size = self.page_size
36
+ else:
37
+ page_size = InterpolatedString(self.page_size, parameters=parameters).eval(self.config)
38
+ if not isinstance(page_size, int):
39
+ raise Exception(f"{page_size} is of type {type(page_size)}. Expected {int}")
40
+ self._page_size = page_size
41
+
42
+ @property
43
+ def initial_token(self) -> Optional[Any]:
44
+ if self.inject_on_first_request:
45
+ return self.start_from_page
46
+ return None
47
+
48
+ def next_page_token(
49
+ self,
50
+ response: requests.Response,
51
+ last_page_size: int,
52
+ last_record: Optional[Record],
53
+ last_page_token_value: Optional[Any],
54
+ ) -> Optional[Any]:
55
+ # Stop paginating when there are fewer records than the page size or the current page has no records
56
+ if (self._page_size and last_page_size < self._page_size) or last_page_size == 0:
57
+ return None
58
+ elif last_page_token_value is None:
59
+ # If the PageIncrement strategy does not inject on the first request, the incoming last_page_token_value
60
+ # may be None. When this is the case, we assume we've already requested the first page specified by
61
+ # start_from_page and must now get the next page
62
+ return self.start_from_page + 1
63
+ elif not isinstance(last_page_token_value, int):
64
+ raise ValueError(
65
+ f"Last page token value {last_page_token_value} for PageIncrement pagination strategy was not an integer"
66
+ )
67
+ else:
68
+ return last_page_token_value + 1
69
+
70
+ def get_page_size(self) -> Optional[int]:
71
+ return self._page_size
@@ -0,0 +1,48 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from abc import abstractmethod
6
+ from dataclasses import dataclass
7
+ from typing import Any, Optional
8
+
9
+ import requests
10
+
11
+ from airbyte_cdk.sources.types import Record
12
+
13
+
14
+ @dataclass
15
+ class PaginationStrategy:
16
+ """
17
+ Defines how to get the next page token
18
+ """
19
+
20
+ @property
21
+ @abstractmethod
22
+ def initial_token(self) -> Optional[Any]:
23
+ """
24
+ Return the initial value of the token
25
+ """
26
+
27
+ @abstractmethod
28
+ def next_page_token(
29
+ self,
30
+ response: requests.Response,
31
+ last_page_size: int,
32
+ last_record: Optional[Record],
33
+ last_page_token_value: Optional[Any],
34
+ ) -> Optional[Any]:
35
+ """
36
+ :param response: response to process
37
+ :param last_page_size: the number of records read from the response
38
+ :param last_record: the last record extracted from the response
39
+ :param last_page_token_value: The current value of the page token made on the last request
40
+ :return: next page token. Returns None if there are no more pages to fetch
41
+ """
42
+ pass
43
+
44
+ @abstractmethod
45
+ def get_page_size(self) -> Optional[int]:
46
+ """
47
+ :return: page size: The number of records to fetch in a page. Returns None if unspecified
48
+ """
@@ -0,0 +1,66 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from abc import ABC, abstractmethod
6
+ from typing import Any, Optional
7
+
8
+ import requests
9
+
10
+ from airbyte_cdk.sources.declarative.incremental.declarative_cursor import DeclarativeCursor
11
+ from airbyte_cdk.sources.declarative.requesters.paginators.strategies.pagination_strategy import (
12
+ PaginationStrategy,
13
+ )
14
+ from airbyte_cdk.sources.streams.concurrent.cursor import ConcurrentCursor
15
+ from airbyte_cdk.sources.types import Record
16
+
17
+
18
+ class PaginationStopCondition(ABC):
19
+ @abstractmethod
20
+ def is_met(self, record: Record) -> bool:
21
+ """
22
+ Given a condition is met, the pagination will stop
23
+
24
+ :param record: a record used to evaluate the condition
25
+ """
26
+ raise NotImplementedError()
27
+
28
+
29
+ class CursorStopCondition(PaginationStopCondition):
30
+ def __init__(
31
+ self,
32
+ cursor: DeclarativeCursor
33
+ | ConcurrentCursor, # migrate to use both old and concurrent versions
34
+ ):
35
+ self._cursor = cursor
36
+
37
+ def is_met(self, record: Record) -> bool:
38
+ return not self._cursor.should_be_synced(record)
39
+
40
+
41
+ class StopConditionPaginationStrategyDecorator(PaginationStrategy):
42
+ def __init__(self, _delegate: PaginationStrategy, stop_condition: PaginationStopCondition):
43
+ self._delegate = _delegate
44
+ self._stop_condition = stop_condition
45
+
46
+ def next_page_token(
47
+ self,
48
+ response: requests.Response,
49
+ last_page_size: int,
50
+ last_record: Optional[Record],
51
+ last_page_token_value: Optional[Any] = None,
52
+ ) -> Optional[Any]:
53
+ # We evaluate in reverse order because the assumption is that most of the APIs using data feed structure
54
+ # will return records in descending order. In terms of performance/memory, we return the records lazily
55
+ if last_record and self._stop_condition.is_met(last_record):
56
+ return None
57
+ return self._delegate.next_page_token(
58
+ response, last_page_size, last_record, last_page_token_value
59
+ )
60
+
61
+ def get_page_size(self) -> Optional[int]:
62
+ return self._delegate.get_page_size()
63
+
64
+ @property
65
+ def initial_token(self) -> Optional[Any]:
66
+ return self._delegate.initial_token
@@ -0,0 +1,117 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass
6
+ from enum import Enum
7
+ from typing import Any, List, Literal, Mapping, MutableMapping, Optional, Union
8
+
9
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
10
+ from airbyte_cdk.sources.types import Config
11
+
12
+
13
+ class RequestOptionType(Enum):
14
+ """
15
+ Describes where to set a value on a request
16
+ """
17
+
18
+ request_parameter = "request_parameter"
19
+ header = "header"
20
+ body_data = "body_data"
21
+ body_json = "body_json"
22
+
23
+
24
+ @dataclass
25
+ class RequestOption:
26
+ """
27
+ Describes an option to set on a request
28
+
29
+ Attributes:
30
+ field_name (str): Describes the name of the parameter to inject. Mutually exclusive with field_path.
31
+ field_path (list(str)): Describes the path to a nested field as a list of field names.
32
+ Only valid for body_json injection type, and mutually exclusive with field_name.
33
+ inject_into (RequestOptionType): Describes where in the HTTP request to inject the parameter
34
+ """
35
+
36
+ inject_into: RequestOptionType
37
+ parameters: InitVar[Mapping[str, Any]]
38
+ field_name: Optional[Union[InterpolatedString, str]] = None
39
+ field_path: Optional[List[Union[InterpolatedString, str]]] = None
40
+
41
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
42
+ # Validate inputs. We should expect either field_name or field_path, but not both
43
+ if self.field_name is None and self.field_path is None:
44
+ raise ValueError("RequestOption requires either a field_name or field_path")
45
+
46
+ if self.field_name is not None and self.field_path is not None:
47
+ raise ValueError(
48
+ "Only one of field_name or field_path can be provided to RequestOption"
49
+ )
50
+
51
+ # Nested field injection is only supported for body JSON injection
52
+ if self.field_path is not None and self.inject_into != RequestOptionType.body_json:
53
+ raise ValueError(
54
+ "Nested field injection is only supported for body JSON injection. Please use a top-level field_name for other injection types."
55
+ )
56
+
57
+ # Convert field_name and field_path into InterpolatedString objects if they are strings
58
+ if self.field_name is not None:
59
+ self.field_name = InterpolatedString.create(self.field_name, parameters=parameters)
60
+ elif self.field_path is not None:
61
+ self.field_path = [
62
+ InterpolatedString.create(segment, parameters=parameters)
63
+ for segment in self.field_path
64
+ ]
65
+
66
+ @property
67
+ def _is_field_path(self) -> bool:
68
+ """Returns whether this option is a field path (ie, a nested field)"""
69
+ return self.field_path is not None
70
+
71
+ def inject_into_request(
72
+ self,
73
+ target: MutableMapping[str, Any],
74
+ value: Any,
75
+ config: Config,
76
+ ) -> None:
77
+ """
78
+ Inject a request option value into a target request structure using either field_name or field_path.
79
+ For non-body-json injection, only top-level field names are supported.
80
+ For body-json injection, both field names and nested field paths are supported.
81
+
82
+ Args:
83
+ target: The request structure to inject the value into
84
+ value: The value to inject
85
+ config: The config object to use for interpolation
86
+ """
87
+ if self._is_field_path:
88
+ if self.inject_into != RequestOptionType.body_json:
89
+ raise ValueError(
90
+ "Nested field injection is only supported for body JSON injection. Please use a top-level field_name for other injection types."
91
+ )
92
+
93
+ assert self.field_path is not None # for type checker
94
+ current = target
95
+ # Convert path segments into strings, evaluating any interpolated segments
96
+ # Example: ["data", "{{ config[user_type] }}", "id"] -> ["data", "admin", "id"]
97
+ *path_parts, final_key = [
98
+ str(
99
+ segment.eval(config=config)
100
+ if isinstance(segment, InterpolatedString)
101
+ else segment
102
+ )
103
+ for segment in self.field_path
104
+ ]
105
+
106
+ # Build a nested dictionary structure and set the final value at the deepest level
107
+ for part in path_parts:
108
+ current = current.setdefault(part, {})
109
+ current[final_key] = value
110
+ else:
111
+ # For non-nested fields, evaluate the field name if it's an interpolated string
112
+ key = (
113
+ self.field_name.eval(config=config)
114
+ if isinstance(self.field_name, InterpolatedString)
115
+ else self.field_name
116
+ )
117
+ target[str(key)] = value
@@ -0,0 +1,23 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from airbyte_cdk.sources.declarative.requesters.request_options.datetime_based_request_options_provider import (
6
+ DatetimeBasedRequestOptionsProvider,
7
+ )
8
+ from airbyte_cdk.sources.declarative.requesters.request_options.default_request_options_provider import (
9
+ DefaultRequestOptionsProvider,
10
+ )
11
+ from airbyte_cdk.sources.declarative.requesters.request_options.interpolated_request_options_provider import (
12
+ InterpolatedRequestOptionsProvider,
13
+ )
14
+ from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
15
+ RequestOptionsProvider,
16
+ )
17
+
18
+ __all__ = [
19
+ "DatetimeBasedRequestOptionsProvider",
20
+ "DefaultRequestOptionsProvider",
21
+ "InterpolatedRequestOptionsProvider",
22
+ "RequestOptionsProvider",
23
+ ]
@@ -0,0 +1,92 @@
1
+ #
2
+ # Copyright (c) 2024 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass
6
+ from typing import Any, Mapping, MutableMapping, Optional, Union
7
+
8
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
9
+ from airbyte_cdk.sources.declarative.requesters.request_option import (
10
+ RequestOption,
11
+ RequestOptionType,
12
+ )
13
+ from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
14
+ RequestOptionsProvider,
15
+ )
16
+ from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
17
+
18
+
19
+ @dataclass
20
+ class DatetimeBasedRequestOptionsProvider(RequestOptionsProvider):
21
+ """
22
+ Request options provider that extracts fields from the stream_slice and injects them into the respective location in the
23
+ outbound request being made
24
+ """
25
+
26
+ config: Config
27
+ parameters: InitVar[Mapping[str, Any]]
28
+ start_time_option: Optional[RequestOption] = None
29
+ end_time_option: Optional[RequestOption] = None
30
+ partition_field_start: Optional[str] = None
31
+ partition_field_end: Optional[str] = None
32
+
33
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
34
+ self._partition_field_start = InterpolatedString.create(
35
+ self.partition_field_start or "start_time", parameters=parameters
36
+ )
37
+ self._partition_field_end = InterpolatedString.create(
38
+ self.partition_field_end or "end_time", parameters=parameters
39
+ )
40
+
41
+ def get_request_params(
42
+ self,
43
+ *,
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 self._get_request_options(RequestOptionType.request_parameter, stream_slice)
49
+
50
+ def get_request_headers(
51
+ self,
52
+ *,
53
+ stream_state: Optional[StreamState] = None,
54
+ stream_slice: Optional[StreamSlice] = None,
55
+ next_page_token: Optional[Mapping[str, Any]] = None,
56
+ ) -> Mapping[str, Any]:
57
+ return self._get_request_options(RequestOptionType.header, stream_slice)
58
+
59
+ def get_request_body_data(
60
+ self,
61
+ *,
62
+ stream_state: Optional[StreamState] = None,
63
+ stream_slice: Optional[StreamSlice] = None,
64
+ next_page_token: Optional[Mapping[str, Any]] = None,
65
+ ) -> Union[Mapping[str, Any], str]:
66
+ return self._get_request_options(RequestOptionType.body_data, stream_slice)
67
+
68
+ def get_request_body_json(
69
+ self,
70
+ *,
71
+ stream_state: Optional[StreamState] = None,
72
+ stream_slice: Optional[StreamSlice] = None,
73
+ next_page_token: Optional[Mapping[str, Any]] = None,
74
+ ) -> Mapping[str, Any]:
75
+ return self._get_request_options(RequestOptionType.body_json, stream_slice)
76
+
77
+ def _get_request_options(
78
+ self, option_type: RequestOptionType, stream_slice: Optional[StreamSlice]
79
+ ) -> Mapping[str, Any]:
80
+ options: MutableMapping[str, Any] = {}
81
+ if not stream_slice:
82
+ return options
83
+
84
+ if self.start_time_option and self.start_time_option.inject_into == option_type:
85
+ start_time_value = stream_slice.get(self._partition_field_start.eval(self.config))
86
+ self.start_time_option.inject_into_request(options, start_time_value, self.config)
87
+
88
+ if self.end_time_option and self.end_time_option.inject_into == option_type:
89
+ end_time_value = stream_slice.get(self._partition_field_end.eval(self.config))
90
+ self.end_time_option.inject_into_request(options, end_time_value, self.config)
91
+
92
+ return options
@@ -0,0 +1,60 @@
1
+ #
2
+ # Copyright (c) 2024 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass
6
+ from typing import Any, Mapping, Optional, Union
7
+
8
+ from airbyte_cdk.sources.declarative.requesters.request_options.request_options_provider import (
9
+ RequestOptionsProvider,
10
+ )
11
+ from airbyte_cdk.sources.types import StreamSlice, StreamState
12
+
13
+
14
+ @dataclass
15
+ class DefaultRequestOptionsProvider(RequestOptionsProvider):
16
+ """
17
+ Request options provider that extracts fields from the stream_slice and injects them into the respective location in the
18
+ outbound request being made
19
+ """
20
+
21
+ parameters: InitVar[Mapping[str, Any]]
22
+
23
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
24
+ pass
25
+
26
+ def get_request_params(
27
+ self,
28
+ *,
29
+ stream_state: Optional[StreamState] = None,
30
+ stream_slice: Optional[StreamSlice] = None,
31
+ next_page_token: Optional[Mapping[str, Any]] = None,
32
+ ) -> Mapping[str, Any]:
33
+ return {}
34
+
35
+ def get_request_headers(
36
+ self,
37
+ *,
38
+ stream_state: Optional[StreamState] = None,
39
+ stream_slice: Optional[StreamSlice] = None,
40
+ next_page_token: Optional[Mapping[str, Any]] = None,
41
+ ) -> Mapping[str, Any]:
42
+ return {}
43
+
44
+ def get_request_body_data(
45
+ self,
46
+ *,
47
+ stream_state: Optional[StreamState] = None,
48
+ stream_slice: Optional[StreamSlice] = None,
49
+ next_page_token: Optional[Mapping[str, Any]] = None,
50
+ ) -> Union[Mapping[str, Any], str]:
51
+ return {}
52
+
53
+ def get_request_body_json(
54
+ self,
55
+ *,
56
+ stream_state: Optional[StreamState] = None,
57
+ stream_slice: Optional[StreamSlice] = None,
58
+ next_page_token: Optional[Mapping[str, Any]] = None,
59
+ ) -> Mapping[str, Any]:
60
+ return {}
@@ -0,0 +1,59 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass, field
6
+ from typing import Any, Mapping, Optional, Union
7
+
8
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_nested_mapping import (
9
+ InterpolatedNestedMapping,
10
+ NestedMapping,
11
+ )
12
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
13
+ from airbyte_cdk.sources.types import Config, StreamSlice
14
+
15
+
16
+ @dataclass
17
+ class InterpolatedNestedRequestInputProvider:
18
+ """
19
+ Helper class that generically performs string interpolation on a provided deeply nested dictionary or string input
20
+ """
21
+
22
+ parameters: InitVar[Mapping[str, Any]]
23
+ request_inputs: Optional[Union[str, NestedMapping]] = field(default=None)
24
+ config: Config = field(default_factory=dict)
25
+ _interpolator: Optional[Union[InterpolatedString, InterpolatedNestedMapping]] = field(
26
+ init=False, repr=False, default=None
27
+ )
28
+ _request_inputs: Optional[Union[str, NestedMapping]] = field(
29
+ init=False, repr=False, default=None
30
+ )
31
+
32
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
33
+ self._request_inputs = self.request_inputs or {}
34
+ if isinstance(self._request_inputs, str):
35
+ self._interpolator = InterpolatedString(
36
+ self._request_inputs, default="", parameters=parameters
37
+ )
38
+ else:
39
+ self._interpolator = InterpolatedNestedMapping(
40
+ self._request_inputs, parameters=parameters
41
+ )
42
+
43
+ def eval_request_inputs(
44
+ self,
45
+ stream_slice: Optional[StreamSlice] = None,
46
+ next_page_token: Optional[Mapping[str, Any]] = None,
47
+ ) -> Mapping[str, Any]:
48
+ """
49
+ Returns the request inputs to set on an outgoing HTTP request
50
+
51
+ :param stream_slice: The stream slice
52
+ :param next_page_token: The pagination token
53
+ :return: The request inputs to set on an outgoing HTTP request
54
+ """
55
+ kwargs = {
56
+ "stream_slice": stream_slice,
57
+ "next_page_token": next_page_token,
58
+ }
59
+ return self._interpolator.eval(self.config, **kwargs) # type: ignore # self._interpolator is always initialized with a value and will not be None
@@ -0,0 +1,68 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+
5
+ from dataclasses import InitVar, dataclass, field
6
+ from typing import Any, Mapping, Optional, Tuple, Type, Union
7
+
8
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping
9
+ from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString
10
+ from airbyte_cdk.sources.types import Config, StreamSlice, StreamState
11
+
12
+
13
+ @dataclass
14
+ class InterpolatedRequestInputProvider:
15
+ """
16
+ Helper class that generically performs string interpolation on the provided dictionary or string input
17
+ """
18
+
19
+ parameters: InitVar[Mapping[str, Any]]
20
+ request_inputs: Optional[Union[str, Mapping[str, str]]] = field(default=None)
21
+ config: Config = field(default_factory=dict)
22
+ _interpolator: Optional[Union[InterpolatedString, InterpolatedMapping]] = field(
23
+ init=False, repr=False, default=None
24
+ )
25
+ _request_inputs: Optional[Union[str, Mapping[str, str]]] = field(
26
+ init=False, repr=False, default=None
27
+ )
28
+
29
+ def __post_init__(self, parameters: Mapping[str, Any]) -> None:
30
+ self._request_inputs = self.request_inputs or {}
31
+ if isinstance(self._request_inputs, str):
32
+ self._interpolator = InterpolatedString(
33
+ self._request_inputs, default="", parameters=parameters
34
+ )
35
+ else:
36
+ self._interpolator = InterpolatedMapping(self._request_inputs, parameters=parameters)
37
+
38
+ def eval_request_inputs(
39
+ self,
40
+ stream_slice: Optional[StreamSlice] = None,
41
+ next_page_token: Optional[Mapping[str, Any]] = None,
42
+ valid_key_types: Optional[Tuple[Type[Any]]] = None,
43
+ valid_value_types: Optional[Tuple[Type[Any], ...]] = None,
44
+ ) -> Mapping[str, Any]:
45
+ """
46
+ Returns the request inputs to set on an outgoing HTTP request
47
+
48
+ :param stream_slice: The stream slice
49
+ :param next_page_token: The pagination token
50
+ :param valid_key_types: A tuple of types that the interpolator should allow
51
+ :param valid_value_types: A tuple of types that the interpolator should allow
52
+ :return: The request inputs to set on an outgoing HTTP request
53
+ """
54
+ kwargs = {
55
+ "stream_slice": stream_slice,
56
+ "next_page_token": next_page_token,
57
+ }
58
+ interpolated_value = self._interpolator.eval( # type: ignore # self._interpolator is always initialized with a value and will not be None
59
+ self.config,
60
+ valid_key_types=valid_key_types,
61
+ valid_value_types=valid_value_types,
62
+ **kwargs,
63
+ )
64
+
65
+ if isinstance(interpolated_value, dict):
66
+ non_null_tokens = {k: v for k, v in interpolated_value.items() if v is not None}
67
+ return non_null_tokens
68
+ return interpolated_value # type: ignore[no-any-return]