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.
- 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
|
)
|