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.
- airbyte_cdk/sources/concurrent_source/__init__.py +3 -0
- airbyte_cdk/sources/concurrent_source/concurrent_read_processor.py +190 -0
- airbyte_cdk/sources/concurrent_source/concurrent_source.py +161 -0
- airbyte_cdk/sources/concurrent_source/concurrent_source_adapter.py +63 -0
- airbyte_cdk/sources/concurrent_source/partition_generation_completed_sentinel.py +17 -0
- airbyte_cdk/sources/concurrent_source/thread_pool_manager.py +97 -0
- airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +16 -4
- airbyte_cdk/sources/declarative/requesters/paginators/default_paginator.py +14 -14
- airbyte_cdk/sources/declarative/requesters/request_options/request_options_provider.py +2 -2
- airbyte_cdk/sources/streams/concurrent/abstract_stream.py +4 -4
- airbyte_cdk/sources/streams/concurrent/adapters.py +34 -12
- airbyte_cdk/sources/streams/concurrent/default_stream.py +79 -0
- airbyte_cdk/sources/streams/concurrent/partition_enqueuer.py +7 -7
- airbyte_cdk/sources/streams/concurrent/partitions/partition.py +23 -0
- airbyte_cdk/sources/streams/concurrent/partitions/record.py +4 -3
- airbyte_cdk/sources/streams/concurrent/partitions/types.py +2 -3
- airbyte_cdk/sources/utils/slice_logger.py +5 -0
- {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/METADATA +1 -1
- {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/RECORD +40 -28
- {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/WHEEL +1 -1
- unit_tests/sources/concurrent_source/__init__.py +3 -0
- unit_tests/sources/concurrent_source/test_concurrent_source_adapter.py +105 -0
- unit_tests/sources/declarative/parsers/test_model_to_component_factory.py +33 -0
- unit_tests/sources/declarative/requesters/paginators/test_default_paginator.py +9 -2
- unit_tests/sources/streams/concurrent/scenarios/stream_facade_builder.py +14 -7
- unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py +2 -3
- unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_scenarios.py +44 -55
- unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py +24 -15
- unit_tests/sources/streams/concurrent/test_adapters.py +52 -32
- unit_tests/sources/streams/concurrent/test_concurrent_partition_generator.py +6 -5
- unit_tests/sources/streams/concurrent/test_concurrent_read_processor.py +604 -0
- unit_tests/sources/streams/concurrent/test_cursor.py +1 -1
- unit_tests/sources/streams/concurrent/{test_thread_based_concurrent_stream.py → test_default_stream.py} +7 -144
- unit_tests/sources/streams/concurrent/test_partition_reader.py +2 -2
- unit_tests/sources/streams/concurrent/test_thread_pool_manager.py +98 -0
- unit_tests/sources/streams/test_stream_read.py +1 -2
- unit_tests/sources/test_concurrent_source.py +105 -0
- unit_tests/sources/test_source_read.py +461 -0
- airbyte_cdk/sources/streams/concurrent/thread_based_concurrent_stream.py +0 -221
- {airbyte_cdk-0.53.9.dist-info → airbyte_cdk-0.55.0.dist-info}/LICENSE.txt +0 -0
- {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=
|
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=
|
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=
|
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=
|
195
|
-
airbyte_cdk/sources/streams/concurrent/adapters.py,sha256=
|
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=
|
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=
|
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
|
207
|
-
airbyte_cdk/sources/streams/concurrent/partitions/types.py,sha256=
|
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=
|
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=
|
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=
|
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=
|
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=
|
386
|
-
unit_tests/sources/streams/concurrent/test_concurrent_partition_generator.py,sha256=
|
387
|
-
unit_tests/sources/streams/concurrent/
|
388
|
-
unit_tests/sources/streams/concurrent/
|
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/
|
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=
|
394
|
-
unit_tests/sources/streams/concurrent/scenarios/stream_facade_scenarios.py,sha256=
|
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=
|
397
|
-
unit_tests/sources/streams/concurrent/scenarios/thread_based_concurrent_stream_source_builder.py,sha256=
|
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.
|
415
|
-
airbyte_cdk-0.
|
416
|
-
airbyte_cdk-0.
|
417
|
-
airbyte_cdk-0.
|
418
|
-
airbyte_cdk-0.
|
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,,
|
@@ -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
|
-
|
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
|
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(
|
29
|
+
class StreamFacadeSource(ConcurrentSourceAdapter):
|
26
30
|
def __init__(
|
27
31
|
self,
|
28
32
|
streams: List[Stream],
|
29
|
-
|
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
|
-
|
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
|
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": "
|
127
|
-
{"level": "INFO", "message": "Finished syncing StreamFacadeSource"},
|
126
|
+
{"level": "INFO", "message": "Finished syncing"},
|
128
127
|
]
|
129
128
|
}
|
130
129
|
)
|