airbyte-cdk 0.53.9__py3-none-any.whl → 0.55.0__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 (41) hide show
  1. airbyte_cdk/sources/concurrent_source/__init__.py +3 -0
  2. airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py +190 -0
  3. airbyte_cdk/sources/concurrent_source/concurrent_source.py +161 -0
  4. airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py +63 -0
  5. airbyte_cdk/sources/concurrent_source/partition_generation_completed_sentinel.py +17 -0
  6. airbyte_cdk/sources/concurrent_source/thread_pool_manager.py +97 -0
  7. airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +16 -4
  8. airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +14 -14
  9. airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +2 -2
  10. airbyte_cdk/sources/streams/concurrent/abstract_stream.py +4 -4
  11. airbyte_cdk/sources/streams/concurrent/adapters.py +34 -12
  12. airbyte_cdk/sources/streams/concurrent/default_stream.py +79 -0
  13. airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py +7 -7
  14. airbyte_cdk/sources/streams/concurrent/partitions/partition.py +23 -0
  15. airbyte_cdk/sources/streams/concurrent/partitions/record.py +4 -3
  16. airbyte_cdk/sources/streams/concurrent/partitions/types.py +2 -3
  17. airbyte_cdk/sources/utils/slice_logger.py +5 -0
  18. {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/METADATA +1 -1
  19. {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/RECORD +40 -28
  20. {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/WHEEL +1 -1
  21. unit_tests/sources/concurrent_source/__init__.py +3 -0
  22. unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py +105 -0
  23. unit_tests/sources/declarative/parsers/test_model_to_component_factory.py +33 -0
  24. unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py +9 -2
  25. unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py +14 -7
  26. unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py +2 -3
  27. unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py +44 -55
  28. unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py +24 -15
  29. unit_tests/sources/streams/concurrent/test_adapters.py +52 -32
  30. unit_tests/sources/streams/concurrent/test_concurrent_partition_generator.py +6 -5
  31. unit_tests/sources/streams/concurrent/test_concurrent_read_processor.py +604 -0
  32. unit_tests/sources/streams/concurrent/test_cursor.py +1 -1
  33. unit_tests/sources/streams/concurrent/{test_thread_based_concurrent_stream.py → test_default_stream.py} +7 -144
  34. unit_tests/sources/streams/concurrent/test_partition_reader.py +2 -2
  35. unit_tests/sources/streams/concurrent/test_thread_pool_manager.py +98 -0
  36. unit_tests/sources/streams/test_stream_read.py +1 -2
  37. unit_tests/sources/test_concurrent_source.py +105 -0
  38. unit_tests/sources/test_source_read.py +461 -0
  39. airbyte_cdk/sources/streams/concurrent/thread_based_concurrent_stream.py +0 -221
  40. {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/LICENSE.txt +0 -0
  41. {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/top_level.txt +0 -0
@@ -30,6 +30,12 @@ airbyte_cdk/sources/connector_state_manager.py,sha256=wsmUgII398MazCTKxwLBLzeiU6
30
30
  airbyte_cdk/sources/http_config.py,sha256=OBZeuyFilm6NlDlBhFQvHhTWabEvZww6OHDIlZujIS0,730
31
31
  airbyte_cdk/sources/http_logger.py,sha256=v0kkpDtA0GUOgj6_3AayrYaBrSHBqG4t3MGbrtxaNmU,1437
32
32
  airbyte_cdk/sources/source.py,sha256=dk50z8Roc28MJ8FxWe652B-GwItO__bTZqFm7WOtHnw,4412
33
+ airbyte_cdk/sources/concurrent_source/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
34
+ airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py,sha256=7A8bdOqg9Hpw37QgqoGO6eYBx8_pKikt_AJUcImp-x4,9715
35
+ airbyte_cdk/sources/concurrent_source/concurrent_source.py,sha256=nmHZLmUwHYW5a8B-XpwVLZ2weys5oWTVYSMseW7WdYc,7836
36
+ airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py,sha256=si5ipxvzCE2Pdusg19evr8ziG7eqBBuBuDPww6i3Amg,3223
37
+ airbyte_cdk/sources/concurrent_source/partition_generation_completed_sentinel.py,sha256=oExaUlnDepGZjNmauIkFDCbWtxZvkBCFo1K0wAr4sRA,493
38
+ airbyte_cdk/sources/concurrent_source/thread_pool_manager.py,sha256=huFp0uuG2kZAnbHY8oeDYuX0hfmP-rLOnJMa72ZuWt0,3905
33
39
  airbyte_cdk/sources/declarative/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
34
40
  airbyte_cdk/sources/declarative/create_partial.py,sha256=sUJOwD8hBzW4pxw2XhYlSTMgl-WMc5WpP5Oq_jo3fHw,3371
35
41
  airbyte_cdk/sources/declarative/declarative_component_schema.yaml,sha256=LtLvEpzKo86RzMO6n20-z4ECW6P0Yoi26HXRCSLP9K0,85049
@@ -80,7 +86,7 @@ airbyte_cdk/sources/declarative/parsers/custom_exceptions.py,sha256=y7_G5mM07zxT
80
86
  airbyte_cdk/sources/declarative/parsers/default_implementation_registry.py,sha256=W8BcK4KOg4ifNXgsdeIoV4oneHjXBKcPHEZHIC4r-hM,3801
81
87
  airbyte_cdk/sources/declarative/parsers/manifest_component_transformer.py,sha256=H23H3nURCxsvjq66Gn9naffp0HJ1fU03wLFu-5F0AhQ,7701
82
88
  airbyte_cdk/sources/declarative/parsers/manifest_reference_resolver.py,sha256=6ukHx0bBrCJm9rek1l_MEfS3U_gdJcM4pJRyifJEOp0,6412
83
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=GU0VrmNJd0rbVadF4_liKz2zFq_-LxHEV4tx10SIMqc,56513
89
+ airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py,sha256=UW87uDnz2UGjEA-w22ncydsyufzRXLIbGXqn0Xr4KwA,56897
84
90
  airbyte_cdk/sources/declarative/partition_routers/__init__.py,sha256=27sOWhw2LBQs62HchURakHQ2M_mtnOatNgU6q8RUtpU,476
85
91
  airbyte_cdk/sources/declarative/partition_routers/list_partition_router.py,sha256=UMK5B3vVN9DYGyMfDkMmeHGF2jgm0iQ_NSggO5v_zqw,4122
86
92
  airbyte_cdk/sources/declarative/partition_routers/single_partition_router.py,sha256=CAbyL0CJRReHZtsyyvZd7X0zE2ELt5CLnE4feDJkx2Y,1575
@@ -105,7 +111,7 @@ airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/hea
105
111
  airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_time_from_header_backoff_strategy.py,sha256=m7MwRtzO_XDpKnKiHTzrr2AtoSZOQ7r4W02gCWgysgk,1464
106
112
  airbyte_cdk/sources/declarative/requesters/error_handlers/backoff_strategies/wait_until_time_from_header_backoff_strategy.py,sha256=H7yeA0JSbxM_ngG4J7LpC62QycjpIGObRoCdCcLalVg,2571
107
113
  airbyte_cdk/sources/declarative/requesters/paginators/__init__.py,sha256=kDH6MR4fYJcVDve9V9Ued45AmEvxFdFPqX9VUN4u_KA,599
108
- airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py,sha256=IRCxL4pFZlqJFvgZdlflJMHKhTsDMPo_w4bWQBn4lkE,9796
114
+ airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py,sha256=GOfdTZ6TRDvV6yThWy_qlHowzF5P-jl8_PIkqvDt4TA,10054
109
115
  airbyte_cdk/sources/declarative/requesters/paginators/no_pagination.py,sha256=Rw0GZaooVXLpSYIXPZ8LmwXB0x2oZ36p6zF3dn3uI5Y,1871
110
116
  airbyte_cdk/sources/declarative/requesters/paginators/paginator.py,sha256=GEULFqQ7kNYjsVdpsztRZg9Rx7uNrLUXFPDGGnB0X4s,1828
111
117
  airbyte_cdk/sources/declarative/requesters/paginators/strategies/__init__.py,sha256=stF494yJa3j2T_IsJWEBh6ds1JTiPNakuTfZ_8Bpfxo,740
@@ -118,7 +124,7 @@ airbyte_cdk/sources/declarative/requesters/request_options/__init__.py,sha256=RH
118
124
  airbyte_cdk/sources/declarative/requesters/request_options/interpolated_nested_request_input_provider.py,sha256=jgy0emr7miFgD-qXkSE1Og_O85qPIjGhPi9JXYgUjuQ,2103
119
125
  airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_input_provider.py,sha256=bU9Qv5JyrS2q1sUUQtO_rYk9VpPXMdS629keIf8gch4,2689
120
126
  airbyte_cdk/sources/declarative/requesters/request_options/interpolated_request_options_provider.py,sha256=l4YAykS4j0CQAfoZ40-RgACJ3xM5_Zs6i23-_kOCDmI,4999
121
- airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py,sha256=tXxM0OPop49gw_EJuhJR5vyayXcg_XORrJlp5X8KydU,2625
127
+ airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py,sha256=zuHp-yfvjAF6w5zARo2LCkds-HqSRT6bXfNkDbAmq7s,2645
122
128
  airbyte_cdk/sources/declarative/retrievers/__init__.py,sha256=IiHXDeKtibRqeWcRUckmSiXfk--u-sFMw3APWK8PCGQ,339
123
129
  airbyte_cdk/sources/declarative/retrievers/retriever.py,sha256=v1WN3mydgftdpD_vGfFjy8bntzYy3qEJjn4iL7ETAcQ,1793
124
130
  airbyte_cdk/sources/declarative/retrievers/simple_retriever.py,sha256=m_0VsF7lBGtZbvHoy8TIeWgWqZeXkbsxhUbTBRtxfbc,18367
@@ -191,20 +197,20 @@ airbyte_cdk/sources/streams/availability_strategy.py,sha256=7BM0qLvXS0QrlKvnVkBE
191
197
  airbyte_cdk/sources/streams/call_rate.py,sha256=5T4J8WxMNov76iXRUtD5KlM1CsROxuAQPwGQAZyvpHg,20555
192
198
  airbyte_cdk/sources/streams/core.py,sha256=bIuQV7Zs9JpIyNDcfPCbyzv-BWDr_2ictK7s5AihLZQ,16025
193
199
  airbyte_cdk/sources/streams/concurrent/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
194
- airbyte_cdk/sources/streams/concurrent/abstract_stream.py,sha256=GCcRvUixoDOkNPy0vK37xdGxYaOfZXxVH6InzndduaE,3525
195
- airbyte_cdk/sources/streams/concurrent/adapters.py,sha256=yYpmVHwRkanyz1Pfm1dbZt_Q93pGnY8cmVKDLwiFTBM,17325
200
+ airbyte_cdk/sources/streams/concurrent/abstract_stream.py,sha256=W7WEz6FrfAjb0o_msnMBIESSVO1qJC2_A8ocYg55Rw4,3579
201
+ airbyte_cdk/sources/streams/concurrent/adapters.py,sha256=kBlHLeHi_xg_rtPMzfyU4Osh-k7K5NLUMOMfAPwiwrk,18090
196
202
  airbyte_cdk/sources/streams/concurrent/availability_strategy.py,sha256=8xDRpfktnARBbRi_RwznvKuoGrpPF2b6tQyloMwogkM,2013
197
203
  airbyte_cdk/sources/streams/concurrent/cursor.py,sha256=vvQeY-IkJ8gfwKfCZTLTVlBYA9gVgQX6bYdWUT0D-q4,6504
204
+ airbyte_cdk/sources/streams/concurrent/default_stream.py,sha256=w83pvFbw9vjfhbovw-LrCFiwQMO8hfo1Vm-1CB1SeXQ,2777
198
205
  airbyte_cdk/sources/streams/concurrent/exceptions.py,sha256=-WETGIY5_QFmVeDFiqm4WhRJ_nNCkfcDwOQqx6cSqrI,365
199
- airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py,sha256=uAUhCkxFOaptDJfIEDmFnnF4xn4coG5kvE4B_5tVx14,1557
206
+ airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py,sha256=Mmn0hYq2xWe2a0WOpZPF3iZNozfmv7vY37LgfdY7DVo,1570
200
207
  airbyte_cdk/sources/streams/concurrent/partition_reader.py,sha256=H8sGVVGx6uKMSUehRaqmVbE19DE3cx3NivQ4sFj8wbk,1303
201
208
  airbyte_cdk/sources/streams/concurrent/state_converter.py,sha256=PwqcRVPR6LQxWL0yvPTp_u2Uh0hBJU-BDSjPKiyJVEk,4689
202
- airbyte_cdk/sources/streams/concurrent/thread_based_concurrent_stream.py,sha256=M7CpPPBswHTYjG4opiTOf5eWHOJ6i4TyP0v991pFxOo,10843
203
209
  airbyte_cdk/sources/streams/concurrent/partitions/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
204
- airbyte_cdk/sources/streams/concurrent/partitions/partition.py,sha256=tjXF8lZMvyfZaCYCHr5aTPwbVstmRjYZDwYAvLDY-ds,1312
210
+ airbyte_cdk/sources/streams/concurrent/partitions/partition.py,sha256=o2QvDYZF3Tn9NbC5jc1UkDwMiCWq9fNGj493u2WFoko,1795
205
211
  airbyte_cdk/sources/streams/concurrent/partitions/partition_generator.py,sha256=_ymkkBr71_qt1fW0_MUqw96OfNBkeJngXQ09yolEDHw,441
206
- airbyte_cdk/sources/streams/concurrent/partitions/record.py,sha256=c87pzwl18pq1_3XLoKDXH_WwrskjbBnTGkxrF4uU5-A,469
207
- airbyte_cdk/sources/streams/concurrent/partitions/types.py,sha256=uc3aBg2kbp3mZry3RtmAwtFExKG2oQw2qG12tZWY514,849
212
+ airbyte_cdk/sources/streams/concurrent/partitions/record.py,sha256=-Q3zLex3CHOXiB-KOZLbBZaPiQ_BLFJdknr6yoRz9I0,600
213
+ airbyte_cdk/sources/streams/concurrent/partitions/types.py,sha256=iVARnsGOSdvlSCqAf-yxc4_PUT3oOR9B6cyVNcLTjY8,932
208
214
  airbyte_cdk/sources/streams/http/__init__.py,sha256=cTP2d7Wf0hYXaN20U0dtxKa1pFZ9rI-lBbkQ0UM1apQ,261
209
215
  airbyte_cdk/sources/streams/http/availability_strategy.py,sha256=MHgW42gwaevaCVnNLrUSE6WJHT4reeZ417nMWrmbC7o,6884
210
216
  airbyte_cdk/sources/streams/http/exceptions.py,sha256=OokLDI7W8hZvq9e15sL3em2AdwmzmcAl72Ms-i5l0Nw,1334
@@ -227,7 +233,7 @@ airbyte_cdk/sources/utils/catalog_helpers.py,sha256=Jo3F6NQE2O7aP4x7yGScwbvtPQyC
227
233
  airbyte_cdk/sources/utils/record_helper.py,sha256=lNtOK1rMUxB9cw6wIi3yNu85jlqTN5inTkZZCWvPKXA,1711
228
234
  airbyte_cdk/sources/utils/schema_helpers.py,sha256=_Kasvdo60OE1aHkrd2Q48OHrMJnZ8nSWliuAVbR7vJs,8483
229
235
  airbyte_cdk/sources/utils/schema_models.py,sha256=m1vOqNkkVYGblc492wKo11Zm5FK9F0-JoNb50aRZnew,3151
230
- airbyte_cdk/sources/utils/slice_logger.py,sha256=Dv0m6Y4YYbHKB-RoMZosKjMgarQZJc4dp7jmKdwilJU,1515
236
+ airbyte_cdk/sources/utils/slice_logger.py,sha256=YeWSoZeOsQp9oZK7mick2J8KFdiY726LY2iiIj_--r4,1731
231
237
  airbyte_cdk/sources/utils/transform.py,sha256=4GYmO6bq33HF-a1in0dKQKqUOYI1bWItyuYF875bSQg,9493
232
238
  airbyte_cdk/sources/utils/types.py,sha256=41ZQR681t5TUnOScij58d088sb99klH_ZENFcaYro_g,175
233
239
  airbyte_cdk/utils/__init__.py,sha256=qZoNqzEKhIXdN_ZfvXlIGnmiDDjCFy6BVCzzWjUZcuU,294
@@ -256,11 +262,15 @@ unit_tests/singer/test_singer_helpers.py,sha256=pZV6VxJuK-3-FICNGmoGbokrA_zkaFZE
256
262
  unit_tests/singer/test_singer_source.py,sha256=edN_kv7dnYAdBveWdUYOs74ak0dK6p8uaX225h_ZILA,4442
257
263
  unit_tests/sources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
258
264
  unit_tests/sources/test_abstract_source.py,sha256=V7zSpOk-jqfOz8FtnImAo_zDe-Q2TjPqD_l_T0QaiDw,48179
265
+ unit_tests/sources/test_concurrent_source.py,sha256=NT4K0z-oz2OZBHE9xNQT0KUdI2wJ-5vNWLUHZlIYKKU,3552
259
266
  unit_tests/sources/test_config.py,sha256=lxjeaf48pOMF4Pf3-Z1ux_tHTyjRFCdG_hpnxw3e7uQ,2839
260
267
  unit_tests/sources/test_connector_state_manager.py,sha256=ynFxA63Cxe6t-wMMh9C6ByTlMAuk8W7H2FikDhnUEQ0,24264
261
268
  unit_tests/sources/test_http_logger.py,sha256=VT6DqgspI3DcRnoBQkkQX0z4dF_AOiYZ5P_zxmMW8oU,9004
262
269
  unit_tests/sources/test_integration_source.py,sha256=7DAWzuYwU_HXzhw-rRjjwQuQej-hVpNyzw_NLqQiJVc,3369
263
270
  unit_tests/sources/test_source.py,sha256=W0I4umL_d_OToLYYiRkjkJR6e-cCYjdV8zKc3uLvF0k,27999
271
+ unit_tests/sources/test_source_read.py,sha256=AEFoJfzM0_5QQIJyKwGLK_kq_Vz_CBivImnUnXJQJ0I,17176
272
+ unit_tests/sources/concurrent_source/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
273
+ unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py,sha256=zsGnMcEsBedjW8wahil6LNqniil-3NXhyZd5W-80Km0,3665
264
274
  unit_tests/sources/declarative/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
265
275
  unit_tests/sources/declarative/external_component.py,sha256=lU2gL736bLEWtmrGm1B2k83RXt_3XkROimLIahZd5dg,293
266
276
  unit_tests/sources/declarative/test_create_partial.py,sha256=s_KIywQqt8RlauOCWNJVk3HC3KBTAtSwFTN6JVQgu80,2636
@@ -295,7 +305,7 @@ unit_tests/sources/declarative/interpolation/test_macros.py,sha256=vEZmHQ0KsfQUz
295
305
  unit_tests/sources/declarative/parsers/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
296
306
  unit_tests/sources/declarative/parsers/test_manifest_component_transformer.py,sha256=5lHUFv2n32b6h5IRh65S7EfqPkP5-IrGE3VUxDoPflI,12483
297
307
  unit_tests/sources/declarative/parsers/test_manifest_reference_resolver.py,sha256=K3q9eyx-sJFQ8nGYjAgS7fxau4sX_FlNreEAjiCYOeE,5306
298
- unit_tests/sources/declarative/parsers/test_model_to_component_factory.py,sha256=jCln_tmsDXkF-YG9ybihIuMrygN7k7Hmk_H_oTbEpEc,70870
308
+ unit_tests/sources/declarative/parsers/test_model_to_component_factory.py,sha256=0zCuA1CTqHuk5Ra8P373Um0V3gqA1G6s5fDw4mzpZ2M,72257
299
309
  unit_tests/sources/declarative/parsers/testing_components.py,sha256=_yUijmYRM-yYHPGDB2JsfEiOuVrgexGW9QwHf1xxNW8,1326
300
310
  unit_tests/sources/declarative/partition_routers/__init__.py,sha256=O8MZg4Bv_DghdRy9BoJCPIqdV75VtiUrhEkExQgb2nE,61
301
311
  unit_tests/sources/declarative/partition_routers/test_list_partition_router.py,sha256=nUqff9W4KwTi4tDdOdu2kqjiWeY02SN2dayiWse0m_4,4210
@@ -317,7 +327,7 @@ unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test
317
327
  unit_tests/sources/declarative/requesters/error_handlers/backoff_strategies/test_wait_until_time_from_header.py,sha256=3RmEjUY_yzWIAsVikvLc3ydLw5PLF7cRH-ymIBgmFC8,3074
318
328
  unit_tests/sources/declarative/requesters/paginators/__init__.py,sha256=ZnqYNxHsKCgO38IwB34RQyRMXTs4GTvlRi3ImKnIioo,61
319
329
  unit_tests/sources/declarative/requesters/paginators/test_cursor_pagination_strategy.py,sha256=eNSjFQAg3mjCe4ixC9qT_bg1EJcJgoMmHn4yCn5eXWg,2957
320
- unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py,sha256=FQfVBD2u4jZIwRpEm9uT-_LddmbJlhYgkiq_h8yN49U,9439
330
+ unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py,sha256=B6v94wOvAC6bIMu2CPj__yEhL0lABr3s0tESBM9K3vY,9741
321
331
  unit_tests/sources/declarative/requesters/paginators/test_no_paginator.py,sha256=rKtHEGtApKbIX1_Fou3kxx_DjcYeaVDIak5_0kJ7J3I,335
322
332
  unit_tests/sources/declarative/requesters/paginators/test_offset_increment.py,sha256=oANM3tk4sTD2z2XpBYgTVpwYjjTCsSpEzGjbSGpnHnA,2607
323
333
  unit_tests/sources/declarative/requesters/paginators/test_page_increment.py,sha256=8HxrlbDRI5PrCpavLZ73HsxQ_SYXBYI_eZhHh1tpRzc,2339
@@ -379,22 +389,24 @@ unit_tests/sources/message/test_repository.py,sha256=oiScwg4cAdnYDl7PPN1nZniDGpA
379
389
  unit_tests/sources/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
380
390
  unit_tests/sources/streams/test_availability_strategy.py,sha256=vJrSEk9NwRghu0YsSNoMYHKWzA9UFemwyClpke8Mk2s,2315
381
391
  unit_tests/sources/streams/test_call_rate.py,sha256=5QsokqxIFoR438QTd7p_eb0K-LW6awZXDtQiMTAb_Qo,13069
382
- unit_tests/sources/streams/test_stream_read.py,sha256=so1M-vf8HxSGq-MVrMymtCvK0abdaT_X9AfV9i0uVm0,6879
392
+ unit_tests/sources/streams/test_stream_read.py,sha256=xxyYV5jPsAptmI0awPO_VGWMaE-y80XMDCB6u87IPaY,6875
383
393
  unit_tests/sources/streams/test_streams_core.py,sha256=YOC7XqWFJ13Z4YuO9Nh4AR4AwpJ-s111vqPplFfpxk4,5059
384
394
  unit_tests/sources/streams/concurrent/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
385
- unit_tests/sources/streams/concurrent/test_adapters.py,sha256=v8_tv2GCUk73DyoiPEPFDBrTRCsXysR-Cw-DXkQnPn4,14743
386
- unit_tests/sources/streams/concurrent/test_concurrent_partition_generator.py,sha256=6ai_6AeRuiUFB0p5TcFGHMG2eiGFbGrmXhI41Oe5XYQ,1321
387
- unit_tests/sources/streams/concurrent/test_cursor.py,sha256=sqH8xE3GamETSSVqsdKafziAAm-y_j_MegES_C5ExMM,5790
388
- unit_tests/sources/streams/concurrent/test_partition_reader.py,sha256=eM5dzfmLKm9Lj-BfQUjAZRhCZzfvhk7AkKpcHGcoPfg,931
395
+ unit_tests/sources/streams/concurrent/test_adapters.py,sha256=Y_c1vKCtGKEzrUSncmpgp0lgFnArmBrIrmLFaOIAxRg,15439
396
+ unit_tests/sources/streams/concurrent/test_concurrent_partition_generator.py,sha256=v8yf19_sDgVcWop6WKotahlQiO6B8MwxhGi3AL4vHm8,1375
397
+ unit_tests/sources/streams/concurrent/test_concurrent_read_processor.py,sha256=1578s0CtFVQALrv2slo12RIgNmNwwobJAFWfBre8jdc,23822
398
+ unit_tests/sources/streams/concurrent/test_cursor.py,sha256=xsQ0zHKzU-iRnpTiAMvGRPbiL50zRJerDoloenkhcj0,5818
399
+ unit_tests/sources/streams/concurrent/test_default_stream.py,sha256=VLF46ESoRqcoALYCdrdZ2NDl5s2T1fRRWsYAy2-IwYw,6502
400
+ unit_tests/sources/streams/concurrent/test_partition_reader.py,sha256=2uj7uV3ie0BMb--aa3MUru-f4jLiYUR-Nl0r3EhwxLQ,951
389
401
  unit_tests/sources/streams/concurrent/test_state_converter.py,sha256=rvg8becWR1iPdm5TAanZssKj5_iw8dInE_uqmjqghZE,8349
390
- unit_tests/sources/streams/concurrent/test_thread_based_concurrent_stream.py,sha256=_jBMJIZ6Hu9mWX4v9SRUdtxvgntA-rQpNbbygBi6HXA,11629
402
+ unit_tests/sources/streams/concurrent/test_thread_pool_manager.py,sha256=7L9Sv7VXULOHx3-KSFwFtzAY1X96wcPiPKGq38BQEVg,3699
391
403
  unit_tests/sources/streams/concurrent/scenarios/__init__.py,sha256=4Hw-PX1-VgESLF16cDdvuYCzGJtHntThLF4qIiULWeo,61
392
404
  unit_tests/sources/streams/concurrent/scenarios/incremental_scenarios.py,sha256=x77AQf8_O4dQ2aF1o800CzI0hOEyU8ayxoNdSOvxkhM,10495
393
- unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py,sha256=FdgEO-bWA_IDFIJb0W83qE4QCCZ8eexbn_Mq8LJq0iE,5040
394
- unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py,sha256=svWqPyIAJCr-TPm0zFk9_gXB8hluVQuet6TqbV6yW3g,14096
405
+ unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py,sha256=OD_9R5fHt5Nf7hH8m28-UDoZJkY8iUBJLI73kd-u2BE,5794
406
+ unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py,sha256=v0yP5MRGYJAb9bp2yXnp5yUmYKJ6aAKjHcNHigL_ONY,13981
395
407
  unit_tests/sources/streams/concurrent/scenarios/test_concurrent_scenarios.py,sha256=sQpvIJa5-Iv03KZfC2sP2zB8XSPCZAjLpUMpNBOA-xM,3897
396
- unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py,sha256=kiZ6VvQywg073FtrpP9AD3yIwSKbalVyfOM2Ksu3sZI,13554
397
- unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py,sha256=G4Em5zfAd9ExzDaD-86nabxWHj9wn5HT3Mfz37UNiME,5310
408
+ unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py,sha256=KqCLsXB_9rV4hNdSPrNynK3G-UIsipqsZT6X0Z-iM5E,13175
409
+ unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py,sha256=aMtEOpCkxH-v2BBOYj4xABzPKcDYh_jieGfaIp4hy9w,5727
398
410
  unit_tests/sources/streams/concurrent/scenarios/utils.py,sha256=Pl1F4asW8AvV6bV5W3Qg21GiLqfdMT_rOt1CsFA0aVM,1953
399
411
  unit_tests/sources/streams/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
400
412
  unit_tests/sources/streams/http/test_availability_strategy.py,sha256=kuQJ5FIc4lffpHmEUVzvoN1QXQzvz8WEkFvzHItiipg,6063
@@ -411,8 +423,8 @@ unit_tests/utils/test_schema_inferrer.py,sha256=Z2jHBZ540wnYkylIdV_2xr75Vtwlxuyg
411
423
  unit_tests/utils/test_secret_utils.py,sha256=XKe0f1RHYii8iwE6ATmBr5JGDI1pzzrnZUGdUSMJQP4,4886
412
424
  unit_tests/utils/test_stream_status_utils.py,sha256=Xr8MZ2HWgTVIyMbywDvuYkRaUF4RZLQOT8-JjvcfR24,2970
413
425
  unit_tests/utils/test_traced_exception.py,sha256=bDFP5zMBizFenz6V2WvEZTRCKGB5ijh3DBezjbfoYIs,4198
414
- airbyte_cdk-0.53.9.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
415
- airbyte_cdk-0.53.9.dist-info/METADATA,sha256=156IehRWmLLOYHL-TeU6EigLZaXLZPzVJ6AGy5dXLCI,11983
416
- airbyte_cdk-0.53.9.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
417
- airbyte_cdk-0.53.9.dist-info/top_level.txt,sha256=edvsDKTnE6sD2wfCUaeTfKf5gQIL6CPVMwVL2sWZzqo,51
418
- airbyte_cdk-0.53.9.dist-info/RECORD,,
426
+ airbyte_cdk-0.55.0.dist-info/LICENSE.txt,sha256=Wfe61S4BaGPj404v8lrAbvhjYR68SHlkzeYrg3_bbuM,1051
427
+ airbyte_cdk-0.55.0.dist-info/METADATA,sha256=2r6pncfFhwFGRcafz2bnvxd-3BwRcgkvHktsJhG0Z8Q,11983
428
+ airbyte_cdk-0.55.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
429
+ airbyte_cdk-0.55.0.dist-info/top_level.txt,sha256=edvsDKTnE6sD2wfCUaeTfKf5gQIL6CPVMwVL2sWZzqo,51
430
+ airbyte_cdk-0.55.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.3)
2
+ Generator: bdist_wheel (0.42.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,3 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
@@ -0,0 +1,105 @@
1
+ #
2
+ # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
+ #
4
+ import logging
5
+ from typing import Any, List, Mapping, Optional, Tuple
6
+ from unittest.mock import Mock
7
+
8
+ import freezegun
9
+ from airbyte_cdk.models import (
10
+ AirbyteMessage,
11
+ AirbyteRecordMessage,
12
+ AirbyteStream,
13
+ ConfiguredAirbyteCatalog,
14
+ ConfiguredAirbyteStream,
15
+ DestinationSyncMode,
16
+ SyncMode,
17
+ )
18
+ from airbyte_cdk.models import Type as MessageType
19
+ from airbyte_cdk.sources.concurrent_source.concurrent_source_adapter import ConcurrentSourceAdapter
20
+ from airbyte_cdk.sources.message import InMemoryMessageRepository
21
+ from airbyte_cdk.sources.streams import Stream
22
+ from airbyte_cdk.sources.streams.concurrent.adapters import StreamFacade
23
+ from airbyte_cdk.sources.streams.concurrent.cursor import NoopCursor
24
+
25
+
26
+ class _MockSource(ConcurrentSourceAdapter):
27
+ def __init__(self, concurrent_source, _streams_to_is_concurrent, logger):
28
+ super().__init__(concurrent_source)
29
+ self._streams_to_is_concurrent = _streams_to_is_concurrent
30
+ self._logger = logger
31
+
32
+ message_repository = InMemoryMessageRepository()
33
+
34
+ def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]:
35
+ raise NotImplementedError
36
+
37
+ def streams(self, config: Mapping[str, Any]) -> List[Stream]:
38
+ return [
39
+ StreamFacade.create_from_stream(s, self, self._logger, None, NoopCursor()) if is_concurrent else s
40
+ for s, is_concurrent in self._streams_to_is_concurrent.items()
41
+ ]
42
+
43
+
44
+ @freezegun.freeze_time("2020-01-01T00:00:00")
45
+ def test_concurrent_source_adapter():
46
+ concurrent_source = Mock()
47
+ message_from_concurrent_stream = AirbyteMessage(
48
+ type=MessageType.RECORD,
49
+ record=AirbyteRecordMessage(
50
+ stream="s2",
51
+ data={"data": 2},
52
+ emitted_at=1577836800000,
53
+ ),
54
+ )
55
+ concurrent_source.read.return_value = iter([message_from_concurrent_stream])
56
+ regular_stream = _mock_stream("s1", [{"data": 1}])
57
+ concurrent_stream = _mock_stream("s2", [])
58
+ unavailable_stream = _mock_stream("s3", [{"data": 3}], False)
59
+ concurrent_stream.name = "s2"
60
+ logger = Mock()
61
+ adapter = _MockSource(concurrent_source, {regular_stream: False, concurrent_stream: True, unavailable_stream: False}, logger)
62
+
63
+ messages = list(adapter.read(logger, {}, _configured_catalog([regular_stream, concurrent_stream, unavailable_stream])))
64
+ records = [m for m in messages if m.type == MessageType.RECORD]
65
+
66
+ expected_records = [
67
+ message_from_concurrent_stream,
68
+ AirbyteMessage(
69
+ type=MessageType.RECORD,
70
+ record=AirbyteRecordMessage(
71
+ stream="s1",
72
+ data={"data": 1},
73
+ emitted_at=1577836800000,
74
+ ),
75
+ ),
76
+ ]
77
+
78
+ assert records == expected_records
79
+
80
+
81
+ def _mock_stream(name: str, data=[], available: bool = True):
82
+ s = Mock()
83
+ s.name = name
84
+ s.as_airbyte_stream.return_value = AirbyteStream(
85
+ name=name,
86
+ json_schema={},
87
+ supported_sync_modes=[SyncMode.full_refresh],
88
+ )
89
+ s.check_availability.return_value = (True, None) if available else (False, "not available")
90
+ s.read_full_refresh.return_value = iter(data)
91
+ s.primary_key = None
92
+ return s
93
+
94
+
95
+ def _configured_catalog(streams: List[Stream]):
96
+ return ConfiguredAirbyteCatalog(
97
+ streams=[
98
+ ConfiguredAirbyteStream(
99
+ stream=stream.as_airbyte_stream(),
100
+ sync_mode=SyncMode.full_refresh,
101
+ destination_sync_mode=DestinationSyncMode.overwrite,
102
+ )
103
+ for stream in streams
104
+ ]
105
+ )
@@ -37,6 +37,8 @@ from airbyte_cdk.sources.declarative.models import RecordSelector as RecordSelec
37
37
  from airbyte_cdk.sources.declarative.models import SimpleRetriever as SimpleRetrieverModel
38
38
  from airbyte_cdk.sources.declarative.models import Spec as SpecModel
39
39
  from airbyte_cdk.sources.declarative.models import SubstreamPartitionRouter as SubstreamPartitionRouterModel
40
+ from airbyte_cdk.sources.declarative.models.declarative_component_schema import OffsetIncrement as OffsetIncrementModel
41
+ from airbyte_cdk.sources.declarative.models.declarative_component_schema import PageIncrement as PageIncrementModel
40
42
  from airbyte_cdk.sources.declarative.parsers.manifest_component_transformer import ManifestComponentTransformer
41
43
  from airbyte_cdk.sources.declarative.parsers.manifest_reference_resolver import ManifestReferenceResolver
42
44
  from airbyte_cdk.sources.declarative.parsers.model_to_component_factory import ModelToComponentFactory
@@ -1706,3 +1708,34 @@ def test_ignore_retry():
1706
1708
  )
1707
1709
 
1708
1710
  assert requester.max_retries == 0
1711
+
1712
+
1713
+ def test_create_page_increment():
1714
+ model = PageIncrementModel(
1715
+ type="PageIncrement",
1716
+ page_size=10,
1717
+ start_from_page=1,
1718
+ inject_on_first_request=True,
1719
+ )
1720
+ expected_strategy = PageIncrement(page_size=10, start_from_page=1, inject_on_first_request=True, parameters={})
1721
+
1722
+ strategy = factory.create_page_increment(model, input_config)
1723
+
1724
+ assert strategy.page_size == expected_strategy.page_size
1725
+ assert strategy.start_from_page == expected_strategy.start_from_page
1726
+ assert strategy.inject_on_first_request == expected_strategy.inject_on_first_request
1727
+
1728
+
1729
+ def test_create_offset_increment():
1730
+ model = OffsetIncrementModel(
1731
+ type="OffsetIncrement",
1732
+ page_size=10,
1733
+ inject_on_first_request=True,
1734
+ )
1735
+ expected_strategy = OffsetIncrement(page_size=10, inject_on_first_request=True, parameters={}, config=input_config)
1736
+
1737
+ strategy = factory.create_offset_increment(model, input_config)
1738
+
1739
+ assert strategy.page_size == expected_strategy.page_size
1740
+ assert strategy.inject_on_first_request == expected_strategy.inject_on_first_request
1741
+ assert strategy.config == input_config
@@ -179,12 +179,19 @@ def test_page_size_option_cannot_be_set_if_strategy_has_no_limit():
179
179
  pass
180
180
 
181
181
 
182
- def test_reset():
182
+ @pytest.mark.parametrize(
183
+ "test_name, inject_on_first_request",
184
+ [
185
+ pytest.param("test_reset_inject_on_first_request", True),
186
+ pytest.param("test_reset_no_inject_on_first_request", False),
187
+ ],
188
+ )
189
+ def test_reset(test_name, inject_on_first_request):
183
190
  page_size_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, field_name="limit", parameters={})
184
191
  page_token_request_option = RequestOption(inject_into=RequestOptionType.request_parameter, field_name="offset", parameters={})
185
192
  url_base = "https://airbyte.io"
186
193
  config = {}
187
- strategy = OffsetIncrement(config={}, page_size=2, parameters={})
194
+ strategy = OffsetIncrement(config={}, page_size=2, inject_on_first_request=inject_on_first_request, parameters={})
188
195
  paginator = DefaultPaginator(
189
196
  strategy, config, url_base, parameters={}, page_size_option=page_size_request_option, page_token_option=page_token_request_option
190
197
  )
@@ -1,11 +1,14 @@
1
1
  #
2
2
  # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
3
  #
4
+ import concurrent
4
5
  import logging
5
6
  from typing import Any, List, Mapping, Optional, Tuple, Union
6
7
 
7
8
  from airbyte_cdk.models import AirbyteStateMessage, ConfiguredAirbyteCatalog, ConnectorSpecification, DestinationSyncMode, SyncMode
8
- from airbyte_cdk.sources import AbstractSource
9
+ from airbyte_cdk.sources.concurrent_source.concurrent_source import ConcurrentSource
10
+ from airbyte_cdk.sources.concurrent_source.concurrent_source_adapter import ConcurrentSourceAdapter
11
+ from airbyte_cdk.sources.concurrent_source.thread_pool_manager import ThreadPoolManager
9
12
  from airbyte_cdk.sources.connector_state_manager import ConnectorStateManager
10
13
  from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository
11
14
  from airbyte_cdk.sources.streams import Stream
@@ -14,6 +17,7 @@ from airbyte_cdk.sources.streams.concurrent.cursor import ConcurrentCursor, Curs
14
17
  from airbyte_cdk.sources.streams.concurrent.state_converter import EpochValueConcurrentStreamStateConverter
15
18
  from airbyte_protocol.models import ConfiguredAirbyteStream
16
19
  from unit_tests.sources.file_based.scenarios.scenario_builder import SourceBuilder
20
+ from unit_tests.sources.streams.concurrent.scenarios.thread_based_concurrent_stream_source_builder import NeverLogSliceLogger
17
21
 
18
22
  _NO_STATE = None
19
23
 
@@ -22,18 +26,21 @@ class StreamFacadeConcurrentConnectorStateConverter(EpochValueConcurrentStreamSt
22
26
  pass
23
27
 
24
28
 
25
- class StreamFacadeSource(AbstractSource):
29
+ class StreamFacadeSource(ConcurrentSourceAdapter):
26
30
  def __init__(
27
31
  self,
28
32
  streams: List[Stream],
29
- max_workers: int,
33
+ threadpool: concurrent.futures.ThreadPoolExecutor,
30
34
  cursor_field: Optional[CursorField] = None,
31
35
  cursor_boundaries: Optional[Tuple[str, str]] = None,
32
36
  input_state: Optional[List[Mapping[str, Any]]] = _NO_STATE,
33
37
  ):
34
- self._streams = streams
35
- self._max_workers = max_workers
36
38
  self._message_repository = InMemoryMessageRepository()
39
+ threadpool_manager = ThreadPoolManager(threadpool, streams[0].logger)
40
+ concurrent_source = ConcurrentSource(threadpool_manager, streams[0].logger, NeverLogSliceLogger(), self._message_repository)
41
+ super().__init__(concurrent_source)
42
+ self._streams = streams
43
+ self._threadpool = threadpool_manager
37
44
  self._cursor_field = cursor_field
38
45
  self._cursor_boundaries = cursor_boundaries
39
46
  self._state = [AirbyteStateMessage.parse_obj(s) for s in input_state] if input_state else None
@@ -49,7 +56,6 @@ class StreamFacadeSource(AbstractSource):
49
56
  stream,
50
57
  self,
51
58
  stream.logger,
52
- self._max_workers,
53
59
  state_converter.get_concurrent_stream_state(state_manager.get_stream_state(stream.name, stream.namespace)),
54
60
  ConcurrentCursor(
55
61
  stream.name,
@@ -115,4 +121,5 @@ class StreamFacadeSourceBuilder(SourceBuilder[StreamFacadeSource]):
115
121
  return self
116
122
 
117
123
  def build(self, configured_catalog: Optional[Mapping[str, Any]]) -> StreamFacadeSource:
118
- return StreamFacadeSource(self._streams, self._max_workers, self._cursor_field, self._cursor_boundaries, self._input_state)
124
+ threadpool = concurrent.futures.ThreadPoolExecutor(max_workers=self._max_workers, thread_name_prefix="workerpool")
125
+ return StreamFacadeSource(self._streams, threadpool, self._cursor_field, self._cursor_boundaries, self._input_state)
@@ -116,15 +116,14 @@ test_stream_facade_single_stream = (
116
116
  .set_expected_logs(
117
117
  {
118
118
  "read": [
119
- {"level": "INFO", "message": "Starting syncing StreamFacadeSource"},
119
+ {"level": "INFO", "message": "Starting syncing"},
120
120
  {"level": "INFO", "message": "Marking stream stream1 as STARTED"},
121
121
  {"level": "INFO", "message": "Syncing stream: stream1"},
122
122
  {"level": "INFO", "message": "Marking stream stream1 as RUNNING"},
123
123
  {"level": "INFO", "message": "Read 2 records from stream1 stream"},
124
124
  {"level": "INFO", "message": "Marking stream stream1 as STOPPED"},
125
125
  {"level": "INFO", "message": "Finished syncing stream1"},
126
- {"level": "INFO", "message": "StreamFacadeSource runtimes"},
127
- {"level": "INFO", "message": "Finished syncing StreamFacadeSource"},
126
+ {"level": "INFO", "message": "Finished syncing"},
128
127
  ]
129
128
  }
130
129
  )