airbyte-cdk 0.53.9__py3-none-any.whl → 0.55.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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
  )