airbyte-source-iterable 0.2.1__py3-none-any.whl → 0.3.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_source_iterable-0.3.0.dist-info/METADATA +113 -0
- {airbyte_source_iterable-0.2.1.dist-info → airbyte_source_iterable-0.3.0.dist-info}/RECORD +9 -26
- {airbyte_source_iterable-0.2.1.dist-info → airbyte_source_iterable-0.3.0.dist-info}/WHEEL +1 -2
- airbyte_source_iterable-0.3.0.dist-info/entry_points.txt +3 -0
- airbyte_source_iterable-0.2.1.dist-info/METADATA +0 -118
- airbyte_source_iterable-0.2.1.dist-info/entry_points.txt +0 -2
- airbyte_source_iterable-0.2.1.dist-info/top_level.txt +0 -3
- integration_tests/__init__.py +0 -0
- integration_tests/abnormal_state.json +0 -74
- integration_tests/acceptance.py +0 -13
- integration_tests/catalog.json +0 -186
- integration_tests/configured_catalog.json +0 -186
- integration_tests/configured_catalog_additional_events.json +0 -291
- integration_tests/invalid_config.json +0 -4
- unit_tests/__init__.py +0 -3
- unit_tests/conftest.py +0 -49
- unit_tests/test_export_adjustable_range.py +0 -117
- unit_tests/test_exports_stream.py +0 -35
- unit_tests/test_slice_generator.py +0 -94
- unit_tests/test_source.py +0 -28
- unit_tests/test_stream_events.py +0 -202
- unit_tests/test_streams.py +0 -270
- unit_tests/test_utils.py +0 -12
@@ -1,186 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"streams": [
|
3
|
-
{
|
4
|
-
"stream": {
|
5
|
-
"name": "campaigns",
|
6
|
-
"json_schema": {},
|
7
|
-
"supported_sync_modes": ["full_refresh"]
|
8
|
-
},
|
9
|
-
"sync_mode": "full_refresh",
|
10
|
-
"destination_sync_mode": "overwrite"
|
11
|
-
},
|
12
|
-
{
|
13
|
-
"stream": {
|
14
|
-
"name": "campaigns_metrics",
|
15
|
-
"json_schema": {},
|
16
|
-
"supported_sync_modes": ["full_refresh"]
|
17
|
-
},
|
18
|
-
"sync_mode": "full_refresh",
|
19
|
-
"destination_sync_mode": "overwrite"
|
20
|
-
},
|
21
|
-
{
|
22
|
-
"stream": {
|
23
|
-
"name": "channels",
|
24
|
-
"json_schema": {},
|
25
|
-
"supported_sync_modes": ["full_refresh"]
|
26
|
-
},
|
27
|
-
"sync_mode": "full_refresh",
|
28
|
-
"destination_sync_mode": "overwrite"
|
29
|
-
},
|
30
|
-
{
|
31
|
-
"stream": {
|
32
|
-
"name": "email_bounce",
|
33
|
-
"json_schema": {},
|
34
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
35
|
-
"source_defined_cursor": true,
|
36
|
-
"default_cursor_field": ["createdAt"]
|
37
|
-
},
|
38
|
-
"sync_mode": "incremental",
|
39
|
-
"destination_sync_mode": "append"
|
40
|
-
},
|
41
|
-
{
|
42
|
-
"stream": {
|
43
|
-
"name": "email_click",
|
44
|
-
"json_schema": {},
|
45
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
46
|
-
"source_defined_cursor": true,
|
47
|
-
"default_cursor_field": ["createdAt"]
|
48
|
-
},
|
49
|
-
"sync_mode": "incremental",
|
50
|
-
"destination_sync_mode": "append"
|
51
|
-
},
|
52
|
-
{
|
53
|
-
"stream": {
|
54
|
-
"name": "email_complaint",
|
55
|
-
"json_schema": {},
|
56
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
57
|
-
"source_defined_cursor": true,
|
58
|
-
"default_cursor_field": ["createdAt"]
|
59
|
-
},
|
60
|
-
"sync_mode": "incremental",
|
61
|
-
"destination_sync_mode": "append"
|
62
|
-
},
|
63
|
-
{
|
64
|
-
"stream": {
|
65
|
-
"name": "email_open",
|
66
|
-
"json_schema": {},
|
67
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
68
|
-
"source_defined_cursor": true,
|
69
|
-
"default_cursor_field": ["createdAt"]
|
70
|
-
},
|
71
|
-
"sync_mode": "incremental",
|
72
|
-
"destination_sync_mode": "append"
|
73
|
-
},
|
74
|
-
{
|
75
|
-
"stream": {
|
76
|
-
"name": "email_send",
|
77
|
-
"json_schema": {},
|
78
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
79
|
-
"source_defined_cursor": true,
|
80
|
-
"default_cursor_field": ["createdAt"]
|
81
|
-
},
|
82
|
-
"sync_mode": "incremental",
|
83
|
-
"destination_sync_mode": "append"
|
84
|
-
},
|
85
|
-
{
|
86
|
-
"stream": {
|
87
|
-
"name": "email_send_skip",
|
88
|
-
"json_schema": {},
|
89
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
90
|
-
"source_defined_cursor": true,
|
91
|
-
"default_cursor_field": ["createdAt"]
|
92
|
-
},
|
93
|
-
"sync_mode": "incremental",
|
94
|
-
"destination_sync_mode": "append"
|
95
|
-
},
|
96
|
-
{
|
97
|
-
"stream": {
|
98
|
-
"name": "email_subscribe",
|
99
|
-
"json_schema": {},
|
100
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
101
|
-
"source_defined_cursor": true,
|
102
|
-
"default_cursor_field": ["createdAt"]
|
103
|
-
},
|
104
|
-
"sync_mode": "incremental",
|
105
|
-
"destination_sync_mode": "append"
|
106
|
-
},
|
107
|
-
{
|
108
|
-
"stream": {
|
109
|
-
"name": "email_unsubscribe",
|
110
|
-
"json_schema": {},
|
111
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
112
|
-
"source_defined_cursor": true,
|
113
|
-
"default_cursor_field": ["createdAt"]
|
114
|
-
},
|
115
|
-
"sync_mode": "incremental",
|
116
|
-
"destination_sync_mode": "append"
|
117
|
-
},
|
118
|
-
{
|
119
|
-
"stream": {
|
120
|
-
"name": "events",
|
121
|
-
"json_schema": {},
|
122
|
-
"supported_sync_modes": ["full_refresh"]
|
123
|
-
},
|
124
|
-
"sync_mode": "full_refresh",
|
125
|
-
"destination_sync_mode": "overwrite"
|
126
|
-
},
|
127
|
-
{
|
128
|
-
"stream": {
|
129
|
-
"name": "lists",
|
130
|
-
"json_schema": {},
|
131
|
-
"supported_sync_modes": ["full_refresh"]
|
132
|
-
},
|
133
|
-
"sync_mode": "full_refresh",
|
134
|
-
"destination_sync_mode": "overwrite"
|
135
|
-
},
|
136
|
-
{
|
137
|
-
"stream": {
|
138
|
-
"name": "list_users",
|
139
|
-
"json_schema": {},
|
140
|
-
"supported_sync_modes": ["full_refresh"]
|
141
|
-
},
|
142
|
-
"sync_mode": "full_refresh",
|
143
|
-
"destination_sync_mode": "overwrite"
|
144
|
-
},
|
145
|
-
{
|
146
|
-
"stream": {
|
147
|
-
"name": "message_types",
|
148
|
-
"json_schema": {},
|
149
|
-
"supported_sync_modes": ["full_refresh"]
|
150
|
-
},
|
151
|
-
"sync_mode": "full_refresh",
|
152
|
-
"destination_sync_mode": "overwrite"
|
153
|
-
},
|
154
|
-
{
|
155
|
-
"stream": {
|
156
|
-
"name": "metadata",
|
157
|
-
"json_schema": {},
|
158
|
-
"supported_sync_modes": ["full_refresh"]
|
159
|
-
},
|
160
|
-
"sync_mode": "full_refresh",
|
161
|
-
"destination_sync_mode": "overwrite"
|
162
|
-
},
|
163
|
-
{
|
164
|
-
"stream": {
|
165
|
-
"name": "users",
|
166
|
-
"json_schema": {},
|
167
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
168
|
-
"source_defined_cursor": true,
|
169
|
-
"default_cursor_field": ["profileUpdatedAt"]
|
170
|
-
},
|
171
|
-
"sync_mode": "incremental",
|
172
|
-
"destination_sync_mode": "append"
|
173
|
-
},
|
174
|
-
{
|
175
|
-
"stream": {
|
176
|
-
"name": "templates",
|
177
|
-
"json_schema": {},
|
178
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
179
|
-
"source_defined_cursor": true,
|
180
|
-
"default_cursor_field": ["createdAt"]
|
181
|
-
},
|
182
|
-
"sync_mode": "incremental",
|
183
|
-
"destination_sync_mode": "append"
|
184
|
-
}
|
185
|
-
]
|
186
|
-
}
|
@@ -1,291 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"streams": [
|
3
|
-
{
|
4
|
-
"stream": {
|
5
|
-
"name": "push_send",
|
6
|
-
"json_schema": {},
|
7
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
8
|
-
"source_defined_cursor": true,
|
9
|
-
"default_cursor_field": ["createdAt"]
|
10
|
-
},
|
11
|
-
"sync_mode": "incremental",
|
12
|
-
"destination_sync_mode": "append"
|
13
|
-
},
|
14
|
-
{
|
15
|
-
"stream": {
|
16
|
-
"name": "push_send_skip",
|
17
|
-
"json_schema": {},
|
18
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
19
|
-
"source_defined_cursor": true,
|
20
|
-
"default_cursor_field": ["createdAt"]
|
21
|
-
},
|
22
|
-
"sync_mode": "incremental",
|
23
|
-
"destination_sync_mode": "append"
|
24
|
-
},
|
25
|
-
{
|
26
|
-
"stream": {
|
27
|
-
"name": "push_open",
|
28
|
-
"json_schema": {},
|
29
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
30
|
-
"source_defined_cursor": true,
|
31
|
-
"default_cursor_field": ["createdAt"]
|
32
|
-
},
|
33
|
-
"sync_mode": "incremental",
|
34
|
-
"destination_sync_mode": "append"
|
35
|
-
},
|
36
|
-
|
37
|
-
{
|
38
|
-
"stream": {
|
39
|
-
"name": "push_uninstall",
|
40
|
-
"json_schema": {},
|
41
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
42
|
-
"source_defined_cursor": true,
|
43
|
-
"default_cursor_field": ["createdAt"]
|
44
|
-
},
|
45
|
-
"sync_mode": "incremental",
|
46
|
-
"destination_sync_mode": "append"
|
47
|
-
},
|
48
|
-
{
|
49
|
-
"stream": {
|
50
|
-
"name": "push_bounce",
|
51
|
-
"json_schema": {},
|
52
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
53
|
-
"source_defined_cursor": true,
|
54
|
-
"default_cursor_field": ["createdAt"]
|
55
|
-
},
|
56
|
-
"sync_mode": "incremental",
|
57
|
-
"destination_sync_mode": "append"
|
58
|
-
},
|
59
|
-
{
|
60
|
-
"stream": {
|
61
|
-
"name": "web_push_send",
|
62
|
-
"json_schema": {},
|
63
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
64
|
-
"source_defined_cursor": true,
|
65
|
-
"default_cursor_field": ["createdAt"]
|
66
|
-
},
|
67
|
-
"sync_mode": "incremental",
|
68
|
-
"destination_sync_mode": "append"
|
69
|
-
},
|
70
|
-
{
|
71
|
-
"stream": {
|
72
|
-
"name": "web_push_click",
|
73
|
-
"json_schema": {},
|
74
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
75
|
-
"source_defined_cursor": true,
|
76
|
-
"default_cursor_field": ["createdAt"]
|
77
|
-
},
|
78
|
-
"sync_mode": "incremental",
|
79
|
-
"destination_sync_mode": "append"
|
80
|
-
},
|
81
|
-
{
|
82
|
-
"stream": {
|
83
|
-
"name": "web_push_send_skip",
|
84
|
-
"json_schema": {},
|
85
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
86
|
-
"source_defined_cursor": true,
|
87
|
-
"default_cursor_field": ["createdAt"]
|
88
|
-
},
|
89
|
-
"sync_mode": "incremental",
|
90
|
-
"destination_sync_mode": "append"
|
91
|
-
},
|
92
|
-
{
|
93
|
-
"stream": {
|
94
|
-
"name": "in_app_send",
|
95
|
-
"json_schema": {},
|
96
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
97
|
-
"source_defined_cursor": true,
|
98
|
-
"default_cursor_field": ["createdAt"]
|
99
|
-
},
|
100
|
-
"sync_mode": "incremental",
|
101
|
-
"destination_sync_mode": "append"
|
102
|
-
},
|
103
|
-
{
|
104
|
-
"stream": {
|
105
|
-
"name": "in_app_open",
|
106
|
-
"json_schema": {},
|
107
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
108
|
-
"source_defined_cursor": true,
|
109
|
-
"default_cursor_field": ["createdAt"]
|
110
|
-
},
|
111
|
-
"sync_mode": "incremental",
|
112
|
-
"destination_sync_mode": "append"
|
113
|
-
},
|
114
|
-
{
|
115
|
-
"stream": {
|
116
|
-
"name": "in_app_click",
|
117
|
-
"json_schema": {},
|
118
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
119
|
-
"source_defined_cursor": true,
|
120
|
-
"default_cursor_field": ["createdAt"]
|
121
|
-
},
|
122
|
-
"sync_mode": "incremental",
|
123
|
-
"destination_sync_mode": "append"
|
124
|
-
},
|
125
|
-
{
|
126
|
-
"stream": {
|
127
|
-
"name": "in_app_close",
|
128
|
-
"json_schema": {},
|
129
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
130
|
-
"source_defined_cursor": true,
|
131
|
-
"default_cursor_field": ["createdAt"]
|
132
|
-
},
|
133
|
-
"sync_mode": "incremental",
|
134
|
-
"destination_sync_mode": "append"
|
135
|
-
},
|
136
|
-
{
|
137
|
-
"stream": {
|
138
|
-
"name": "in_app_delete",
|
139
|
-
"json_schema": {},
|
140
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
141
|
-
"source_defined_cursor": true,
|
142
|
-
"default_cursor_field": ["createdAt"]
|
143
|
-
},
|
144
|
-
"sync_mode": "incremental",
|
145
|
-
"destination_sync_mode": "append"
|
146
|
-
},
|
147
|
-
{
|
148
|
-
"stream": {
|
149
|
-
"name": "in_app_delivery",
|
150
|
-
"json_schema": {},
|
151
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
152
|
-
"source_defined_cursor": true,
|
153
|
-
"default_cursor_field": ["createdAt"]
|
154
|
-
},
|
155
|
-
"sync_mode": "incremental",
|
156
|
-
"destination_sync_mode": "append"
|
157
|
-
},
|
158
|
-
{
|
159
|
-
"stream": {
|
160
|
-
"name": "in_app_send_skip",
|
161
|
-
"json_schema": {},
|
162
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
163
|
-
"source_defined_cursor": true,
|
164
|
-
"default_cursor_field": ["createdAt"]
|
165
|
-
},
|
166
|
-
"sync_mode": "incremental",
|
167
|
-
"destination_sync_mode": "append"
|
168
|
-
},
|
169
|
-
{
|
170
|
-
"stream": {
|
171
|
-
"name": "inbox_session",
|
172
|
-
"json_schema": {},
|
173
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
174
|
-
"source_defined_cursor": true,
|
175
|
-
"default_cursor_field": ["createdAt"]
|
176
|
-
},
|
177
|
-
"sync_mode": "incremental",
|
178
|
-
"destination_sync_mode": "append"
|
179
|
-
},
|
180
|
-
{
|
181
|
-
"stream": {
|
182
|
-
"name": "inbox_message_impression",
|
183
|
-
"json_schema": {},
|
184
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
185
|
-
"source_defined_cursor": true,
|
186
|
-
"default_cursor_field": ["createdAt"]
|
187
|
-
},
|
188
|
-
"sync_mode": "incremental",
|
189
|
-
"destination_sync_mode": "append"
|
190
|
-
},
|
191
|
-
{
|
192
|
-
"stream": {
|
193
|
-
"name": "sms_send",
|
194
|
-
"json_schema": {},
|
195
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
196
|
-
"source_defined_cursor": true,
|
197
|
-
"default_cursor_field": ["createdAt"]
|
198
|
-
},
|
199
|
-
"sync_mode": "incremental",
|
200
|
-
"destination_sync_mode": "append"
|
201
|
-
},
|
202
|
-
{
|
203
|
-
"stream": {
|
204
|
-
"name": "sms_bounce",
|
205
|
-
"json_schema": {},
|
206
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
207
|
-
"source_defined_cursor": true,
|
208
|
-
"default_cursor_field": ["createdAt"]
|
209
|
-
},
|
210
|
-
"sync_mode": "incremental",
|
211
|
-
"destination_sync_mode": "append"
|
212
|
-
},
|
213
|
-
{
|
214
|
-
"stream": {
|
215
|
-
"name": "sms_click",
|
216
|
-
"json_schema": {},
|
217
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
218
|
-
"source_defined_cursor": true,
|
219
|
-
"default_cursor_field": ["createdAt"]
|
220
|
-
},
|
221
|
-
"sync_mode": "incremental",
|
222
|
-
"destination_sync_mode": "append"
|
223
|
-
},
|
224
|
-
{
|
225
|
-
"stream": {
|
226
|
-
"name": "sms_received",
|
227
|
-
"json_schema": {},
|
228
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
229
|
-
"source_defined_cursor": true,
|
230
|
-
"default_cursor_field": ["createdAt"]
|
231
|
-
},
|
232
|
-
"sync_mode": "incremental",
|
233
|
-
"destination_sync_mode": "append"
|
234
|
-
},
|
235
|
-
{
|
236
|
-
"stream": {
|
237
|
-
"name": "sms_send_skip",
|
238
|
-
"json_schema": {},
|
239
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
240
|
-
"source_defined_cursor": true,
|
241
|
-
"default_cursor_field": ["createdAt"]
|
242
|
-
},
|
243
|
-
"sync_mode": "incremental",
|
244
|
-
"destination_sync_mode": "append"
|
245
|
-
},
|
246
|
-
{
|
247
|
-
"stream": {
|
248
|
-
"name": "sms_usage_info",
|
249
|
-
"json_schema": {},
|
250
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
251
|
-
"source_defined_cursor": true,
|
252
|
-
"default_cursor_field": ["createdAt"]
|
253
|
-
},
|
254
|
-
"sync_mode": "incremental",
|
255
|
-
"destination_sync_mode": "append"
|
256
|
-
},
|
257
|
-
{
|
258
|
-
"stream": {
|
259
|
-
"name": "purchase",
|
260
|
-
"json_schema": {},
|
261
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
262
|
-
"source_defined_cursor": true,
|
263
|
-
"default_cursor_field": ["createdAt"]
|
264
|
-
},
|
265
|
-
"sync_mode": "incremental",
|
266
|
-
"destination_sync_mode": "append"
|
267
|
-
},
|
268
|
-
{
|
269
|
-
"stream": {
|
270
|
-
"name": "custom_event",
|
271
|
-
"json_schema": {},
|
272
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
273
|
-
"source_defined_cursor": true,
|
274
|
-
"default_cursor_field": ["createdAt"]
|
275
|
-
},
|
276
|
-
"sync_mode": "incremental",
|
277
|
-
"destination_sync_mode": "append"
|
278
|
-
},
|
279
|
-
{
|
280
|
-
"stream": {
|
281
|
-
"name": "hosted_unsubscribe_click",
|
282
|
-
"json_schema": {},
|
283
|
-
"supported_sync_modes": ["full_refresh", "incremental"],
|
284
|
-
"source_defined_cursor": true,
|
285
|
-
"default_cursor_field": ["createdAt"]
|
286
|
-
},
|
287
|
-
"sync_mode": "incremental",
|
288
|
-
"destination_sync_mode": "append"
|
289
|
-
}
|
290
|
-
]
|
291
|
-
}
|
unit_tests/__init__.py
DELETED
unit_tests/conftest.py
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
-
#
|
4
|
-
|
5
|
-
import pytest
|
6
|
-
from airbyte_cdk.models import AirbyteStream, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream
|
7
|
-
|
8
|
-
|
9
|
-
@pytest.fixture(autouse=True)
|
10
|
-
def disable_cache(mocker):
|
11
|
-
mocker.patch("source_iterable.streams.ListUsers.use_cache", False)
|
12
|
-
|
13
|
-
|
14
|
-
@pytest.fixture
|
15
|
-
def catalog(request):
|
16
|
-
return ConfiguredAirbyteCatalog(
|
17
|
-
streams=[
|
18
|
-
ConfiguredAirbyteStream(
|
19
|
-
stream=AirbyteStream(name=request.param, json_schema={}, supported_sync_modes=["full_refresh"]),
|
20
|
-
sync_mode="full_refresh",
|
21
|
-
destination_sync_mode="append",
|
22
|
-
)
|
23
|
-
]
|
24
|
-
)
|
25
|
-
|
26
|
-
|
27
|
-
@pytest.fixture(name="config")
|
28
|
-
def config_fixture():
|
29
|
-
return {"api_key": 123, "start_date": "2019-10-10T00:00:00"}
|
30
|
-
|
31
|
-
|
32
|
-
@pytest.fixture()
|
33
|
-
def mock_lists_resp(mocker):
|
34
|
-
mocker.patch("source_iterable.streams.Lists.read_records", return_value=iter([{"id": 1}, {"id": 2}]))
|
35
|
-
|
36
|
-
|
37
|
-
@pytest.fixture(name="lists_stream")
|
38
|
-
def lists_stream():
|
39
|
-
# local imports
|
40
|
-
from source_iterable.streams import Lists
|
41
|
-
|
42
|
-
# return the instance of the stream so we could make global tests on it,
|
43
|
-
# to cover the different `should_retry` logic
|
44
|
-
return Lists(authenticator=None)
|
45
|
-
|
46
|
-
|
47
|
-
@pytest.fixture(autouse=True)
|
48
|
-
def mock_sleep(mocker):
|
49
|
-
mocker.patch("time.sleep")
|
@@ -1,117 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
-
#
|
4
|
-
|
5
|
-
import datetime
|
6
|
-
import json
|
7
|
-
import urllib.parse
|
8
|
-
from typing import List
|
9
|
-
from unittest import mock
|
10
|
-
|
11
|
-
import freezegun
|
12
|
-
import pendulum
|
13
|
-
import pytest
|
14
|
-
import responses
|
15
|
-
from airbyte_cdk.models import Type as MessageType
|
16
|
-
from requests.exceptions import ChunkedEncodingError
|
17
|
-
from source_iterable.slice_generators import AdjustableSliceGenerator
|
18
|
-
from source_iterable.source import SourceIterable
|
19
|
-
|
20
|
-
TEST_START_DATE = "2020"
|
21
|
-
|
22
|
-
|
23
|
-
@pytest.fixture
|
24
|
-
def time_mock(request):
|
25
|
-
with freezegun.freeze_time() as time_mock:
|
26
|
-
yield time_mock
|
27
|
-
|
28
|
-
|
29
|
-
def get_range_days_from_request(request):
|
30
|
-
query = urllib.parse.urlsplit(request.url).query
|
31
|
-
query = urllib.parse.parse_qs(query)
|
32
|
-
return (pendulum.parse(query["endDateTime"][0]) - pendulum.parse(query["startDateTime"][0])).days
|
33
|
-
|
34
|
-
|
35
|
-
@mock.patch("logging.getLogger", mock.MagicMock())
|
36
|
-
def read_from_source(catalog):
|
37
|
-
return list(
|
38
|
-
SourceIterable().read(
|
39
|
-
mock.MagicMock(),
|
40
|
-
{"start_date": TEST_START_DATE, "api_key": "api_key"},
|
41
|
-
catalog,
|
42
|
-
None,
|
43
|
-
)
|
44
|
-
)
|
45
|
-
|
46
|
-
|
47
|
-
@responses.activate
|
48
|
-
@pytest.mark.parametrize("catalog", (["email_send"]), indirect=True)
|
49
|
-
def test_email_stream(mock_lists_resp, catalog, time_mock):
|
50
|
-
DAYS_DURATION = 100
|
51
|
-
DAYS_PER_MINUTE_RATE = 8
|
52
|
-
|
53
|
-
time_mock.move_to(pendulum.parse(TEST_START_DATE) + pendulum.Duration(days=DAYS_DURATION))
|
54
|
-
|
55
|
-
ranges: List[int] = []
|
56
|
-
|
57
|
-
def response_cb(req):
|
58
|
-
days = get_range_days_from_request(req)
|
59
|
-
ranges.append(days)
|
60
|
-
time_mock.tick(delta=datetime.timedelta(minutes=days / DAYS_PER_MINUTE_RATE))
|
61
|
-
return (200, {}, json.dumps({"createdAt": "2020"}))
|
62
|
-
|
63
|
-
responses.add(responses.GET, "https://api.iterable.com/api/lists/getUsers?listId=1", json={"lists": [{"id": 1}]}, status=200)
|
64
|
-
responses.add_callback("GET", "https://api.iterable.com/api/export/data.json", callback=response_cb)
|
65
|
-
|
66
|
-
records = read_from_source(catalog)
|
67
|
-
assert records
|
68
|
-
assert sum(ranges) == DAYS_DURATION
|
69
|
-
# since read is called on source instance, under the hood .streams() is called which triggers one more http call
|
70
|
-
assert len(responses.calls) == len(ranges) + 1
|
71
|
-
assert ranges == [
|
72
|
-
AdjustableSliceGenerator.INITIAL_RANGE_DAYS,
|
73
|
-
*([int(DAYS_PER_MINUTE_RATE / AdjustableSliceGenerator.REQUEST_PER_MINUTE_LIMIT)] * 35),
|
74
|
-
]
|
75
|
-
|
76
|
-
|
77
|
-
@responses.activate
|
78
|
-
@pytest.mark.parametrize(
|
79
|
-
"catalog, days_duration, days_per_minute_rate",
|
80
|
-
[
|
81
|
-
("email_send", 10, 200),
|
82
|
-
("email_send", 100, 200000),
|
83
|
-
("email_send", 10000, 200000),
|
84
|
-
("email_click", 1000, 20),
|
85
|
-
("email_open", 1000, 1),
|
86
|
-
("email_open", 1, 1000),
|
87
|
-
("email_open", 0, 1000000),
|
88
|
-
],
|
89
|
-
indirect=["catalog"],
|
90
|
-
)
|
91
|
-
def test_email_stream_chunked_encoding(mocker, mock_lists_resp, catalog, days_duration, days_per_minute_rate, time_mock):
|
92
|
-
mocker.patch("time.sleep")
|
93
|
-
time_mock.move_to(pendulum.parse(TEST_START_DATE) + pendulum.Duration(days=days_duration))
|
94
|
-
|
95
|
-
ranges: List[int] = []
|
96
|
-
encoding_throw = 0
|
97
|
-
|
98
|
-
def response_cb(req):
|
99
|
-
nonlocal encoding_throw
|
100
|
-
# Every request fails with 2 ChunkedEncodingError exception but works well on third time.
|
101
|
-
if encoding_throw < 2:
|
102
|
-
encoding_throw += 1
|
103
|
-
raise ChunkedEncodingError()
|
104
|
-
encoding_throw = 0
|
105
|
-
days = get_range_days_from_request(req)
|
106
|
-
ranges.append(days)
|
107
|
-
time_mock.tick(delta=datetime.timedelta(minutes=days / days_per_minute_rate))
|
108
|
-
return (200, {}, json.dumps({"createdAt": "2020"}))
|
109
|
-
|
110
|
-
responses.add(responses.GET, "https://api.iterable.com/api/lists/getUsers?listId=1", json={"lists": [{"id": 1}]}, status=200)
|
111
|
-
responses.add_callback("GET", "https://api.iterable.com/api/export/data.json", callback=response_cb)
|
112
|
-
# added condition because read_from_source also returns LOG messages
|
113
|
-
records = [record for record in read_from_source(catalog) if record.type == MessageType.RECORD]
|
114
|
-
assert sum(ranges) == days_duration
|
115
|
-
assert len(ranges) == len(records)
|
116
|
-
# since read is called on source instance, under the hood .streams() is called which triggers one more http call
|
117
|
-
assert len(responses.calls) == 3 * len(ranges) + 1
|
@@ -1,35 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
3
|
-
#
|
4
|
-
|
5
|
-
import json
|
6
|
-
from unittest import mock
|
7
|
-
|
8
|
-
import pendulum
|
9
|
-
import pytest
|
10
|
-
import responses
|
11
|
-
from airbyte_cdk.models import SyncMode
|
12
|
-
from source_iterable.slice_generators import StreamSlice
|
13
|
-
from source_iterable.streams import Users
|
14
|
-
|
15
|
-
|
16
|
-
@pytest.fixture
|
17
|
-
def session_mock():
|
18
|
-
with mock.patch("airbyte_cdk.sources.streams.http.http.requests") as requests_mock:
|
19
|
-
session_mock = mock.MagicMock()
|
20
|
-
response_mock = mock.MagicMock()
|
21
|
-
requests_mock.Session.return_value = session_mock
|
22
|
-
session_mock.send.return_value = response_mock
|
23
|
-
response_mock.status_code = 200
|
24
|
-
yield session_mock
|
25
|
-
|
26
|
-
@responses.activate
|
27
|
-
def test_stream_correct():
|
28
|
-
stream_slice = StreamSlice(start_date=pendulum.parse("2020"), end_date=pendulum.parse("2021"))
|
29
|
-
record_js = {"profileUpdatedAt": "2020"}
|
30
|
-
NUMBER_OF_RECORDS = 10**2
|
31
|
-
resp_body = "\n".join([json.dumps(record_js)] * NUMBER_OF_RECORDS)
|
32
|
-
responses.add("GET", "https://api.iterable.com/api/export/data.json", body=resp_body)
|
33
|
-
stream = Users(start_date="2020", authenticator=None)
|
34
|
-
records = list(stream.read_records(sync_mode=SyncMode.full_refresh, cursor_field=None, stream_slice=stream_slice, stream_state={}))
|
35
|
-
assert len(records) == NUMBER_OF_RECORDS
|