airbyte-source-iterable 0.5.11__py3-none-any.whl → 0.6.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-source-iterable
3
- Version: 0.5.11
3
+ Version: 0.6.1
4
4
  Summary: Source implementation for Iterable.
5
5
  Home-page: https://airbyte.com
6
6
  License: MIT
@@ -12,10 +12,9 @@ Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
- Requires-Dist: airbyte-cdk (==0.90.0)
15
+ Requires-Dist: airbyte-cdk (>=3,<4)
16
16
  Requires-Dist: pendulum (==2.1.2)
17
17
  Requires-Dist: python-dateutil (==2.8.2)
18
- Requires-Dist: requests (==2.31.0)
19
18
  Project-URL: Documentation, https://docs.airbyte.com/integrations/sources/iterable
20
19
  Project-URL: Repository, https://github.com/airbytehq/airbyte
21
20
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  source_iterable/__init__.py,sha256=8WKQT800ggxG1vGPoA_ZHUkozwEM7qMhGMhzEPCdA4o,65
2
- source_iterable/components.py,sha256=dHp23THc43TmogP_tCxcv12mAgZSRs5fKir2ckr4hHI,1374
3
- source_iterable/manifest.yaml,sha256=uO7z-bIU6CtGms6IsLwjyZ-cb3tVY-vLUMLOZGkZDts,13996
2
+ source_iterable/components.py,sha256=IuLcldPEti2hc8v4-KyTCLFla0pyuK0EBa7liHUS2wk,805
3
+ source_iterable/manifest.yaml,sha256=BL0mAODdqpiRycEG5igczmkCA7y2VhDnqCAHrsPbUc4,14136
4
4
  source_iterable/run.py,sha256=-Bvz772Z7iJWExDoJS7chxv725hG4e9e5Engrtp66iE,236
5
5
  source_iterable/schemas/campaigns.json,sha256=FONoPuz_4aRat8OZzhj7BcHFAqetpBYUDmOZfroCu7I,2494
6
6
  source_iterable/schemas/campaigns_metrics.json,sha256=Aa6pNdVxHOG-LSxlLzhxFY8uIdfrPBTgX9QyWrLJ4Fs,168
@@ -23,9 +23,9 @@ source_iterable/schemas/users.json,sha256=CHqA30cnsTXfI-M0n54NwVaaZEO12tt_IgQ9yP
23
23
  source_iterable/slice_generators.py,sha256=neRuWD52Xnr84KvWQ0kjaErR44sOKjxIyLCNeofohzE,6482
24
24
  source_iterable/source.py,sha256=AhZQ4L54VTo6jf2QltvFCqDNgqaPSEKCfR0GInCLEEc,4537
25
25
  source_iterable/spec.json,sha256=y5_YFTkPPtxjvzGtaZZql90Tc37fyZZpQKXFGPL_cYE,1009
26
- source_iterable/streams.py,sha256=r6YZlquKUQCyoKlwdIOVMUCTCBLiQPS4POJKmuZD61s,19913
27
- source_iterable/utils.py,sha256=2oM8AjBZXs9nTG_PhSWmxBWEmp-w-tWFaxQQvAfUuMM,649
28
- airbyte_source_iterable-0.5.11.dist-info/METADATA,sha256=YD5fm3-HhbbWhuLoFG-RPNk4dbQ3_Me6NZURgNTxFwE,5368
29
- airbyte_source_iterable-0.5.11.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
30
- airbyte_source_iterable-0.5.11.dist-info/entry_points.txt,sha256=pjzrNtsOX3jW37IK0U5pSmLiraiuLTPr5aB5-hBXpAo,59
31
- airbyte_source_iterable-0.5.11.dist-info/RECORD,,
26
+ source_iterable/streams.py,sha256=wig4zwcSmEIgayutBmrPwhHv4I1ZAuEDLGEkt479NAk,19940
27
+ source_iterable/utils.py,sha256=08uzNpJGDd3uogybhfAtrqBz4lFsldURWyt5OFpz79s,562
28
+ airbyte_source_iterable-0.6.1.dist-info/METADATA,sha256=kpUjHEV8-tTTsnov1wKp_o9kWQI9MjhDhdIougpotms,5330
29
+ airbyte_source_iterable-0.6.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
30
+ airbyte_source_iterable-0.6.1.dist-info/entry_points.txt,sha256=pjzrNtsOX3jW37IK0U5pSmLiraiuLTPr5aB5-hBXpAo,59
31
+ airbyte_source_iterable-0.6.1.dist-info/RECORD,,
@@ -2,40 +2,21 @@
2
2
  # Copyright (c) 2023 Airbyte, Inc., all rights reserved.
3
3
  #
4
4
 
5
- import json
6
5
  from dataclasses import dataclass
7
- from io import StringIO
6
+ from typing import Any, Iterable, Mapping
8
7
 
9
8
  import requests
10
9
  from airbyte_cdk.sources.declarative.extractors.dpath_extractor import DpathExtractor
11
- from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState
12
-
13
-
14
- @dataclass
15
- class XJsonRecordExtractor(DpathExtractor):
16
- def extract_records(self, response: requests.Response) -> list[Record]:
17
- return [json.loads(record) for record in response.iter_lines()]
18
-
19
-
20
- @dataclass
21
- class ListUsersRecordExtractor(DpathExtractor):
22
- def extract_records(self, response: requests.Response) -> list[Record]:
23
- return [{"email": record.decode()} for record in response.iter_lines()]
24
10
 
25
11
 
26
12
  @dataclass
27
13
  class EventsRecordExtractor(DpathExtractor):
28
14
  common_fields = ("itblInternal", "_type", "createdAt", "email")
29
15
 
30
- def extract_records(self, response: requests.Response) -> list[Record]:
31
- jsonl_records = StringIO(response.text)
32
- records = []
33
- for record in jsonl_records:
34
- record_dict = json.loads(record)
16
+ def extract_records(self, response: requests.Response) -> Iterable[Mapping[str, Any]]:
17
+ jsonl_records = super().extract_records(response=response)
18
+ for record_dict in jsonl_records:
35
19
  record_dict_common_fields = {}
36
20
  for field in self.common_fields:
37
21
  record_dict_common_fields[field] = record_dict.pop(field, None)
38
-
39
- records.append({**record_dict_common_fields, "data": record_dict})
40
-
41
- return records
22
+ yield {**record_dict_common_fields, "data": record_dict}
@@ -67,6 +67,8 @@ streams:
67
67
  type: DeclarativeStream
68
68
  retriever:
69
69
  type: SimpleRetriever
70
+ decoder:
71
+ type: IterableDecoder
70
72
  paginator:
71
73
  type: NoPagination
72
74
  requester:
@@ -87,9 +89,8 @@ streams:
87
89
  record_selector:
88
90
  type: RecordSelector
89
91
  extractor:
90
- class_name: source_iterable.components.ListUsersRecordExtractor
91
- field_path:
92
- - getUsers
92
+ type: DpathExtractor
93
+ field_path: []
93
94
  partition_router:
94
95
  - type: SubstreamPartitionRouter
95
96
  parent_stream_configs:
@@ -139,6 +140,12 @@ streams:
139
140
  - path:
140
141
  - listId
141
142
  value: "{{ stream_slice.list_id }}"
143
+ - path:
144
+ - email
145
+ value: "{{ record.record }}"
146
+ - type: RemoveFields
147
+ field_pointers:
148
+ - - record
142
149
  - name: campaigns
143
150
  type: DeclarativeStream
144
151
  retriever:
@@ -262,6 +269,8 @@ streams:
262
269
  type: DeclarativeStream
263
270
  retriever:
264
271
  type: SimpleRetriever
272
+ decoder:
273
+ type: JsonlDecoder
265
274
  paginator:
266
275
  type: NoPagination
267
276
  requester:
@@ -284,9 +293,8 @@ streams:
284
293
  record_selector:
285
294
  type: RecordSelector
286
295
  extractor:
287
- class_name: source_iterable.components.XJsonRecordExtractor
288
- field_path:
289
- - users
296
+ type: DpathExtractor
297
+ field_path: []
290
298
  partition_router: []
291
299
  primary_key: []
292
300
  incremental_sync:
@@ -318,6 +326,8 @@ streams:
318
326
  primary_key: []
319
327
  retriever:
320
328
  type: SimpleRetriever
329
+ decoder:
330
+ type: JsonlDecoder
321
331
  requester:
322
332
  type: HttpRequester
323
333
  url_base: https://api.iterable.com/api/
@@ -338,15 +348,14 @@ streams:
338
348
  type: RecordSelector
339
349
  extractor:
340
350
  class_name: source_iterable.components.EventsRecordExtractor
341
- field_path:
342
- - events
351
+ field_path: []
343
352
  paginator:
344
353
  type: NoPagination
345
354
  partition_router:
346
355
  - type: SubstreamPartitionRouter
347
356
  parent_stream_configs:
348
357
  - type: ParentStreamConfig
349
- parent_key: email
358
+ parent_key: record
350
359
  request_option:
351
360
  inject_into: request_parameter
352
361
  type: RequestOption
@@ -357,6 +366,8 @@ streams:
357
366
  type: DeclarativeStream
358
367
  retriever:
359
368
  type: SimpleRetriever
369
+ decoder:
370
+ type: IterableDecoder
360
371
  paginator:
361
372
  type: NoPagination
362
373
  requester:
@@ -377,9 +388,8 @@ streams:
377
388
  record_selector:
378
389
  type: RecordSelector
379
390
  extractor:
380
- class_name: source_iterable.components.ListUsersRecordExtractor
381
- field_path:
382
- - getUsers
391
+ type: DpathExtractor
392
+ field_path: []
383
393
  partition_router:
384
394
  - type: SubstreamPartitionRouter
385
395
  parent_stream_configs:
@@ -17,7 +17,7 @@ from airbyte_cdk.sources.streams.http import HttpStream
17
17
  from airbyte_cdk.sources.streams.http.exceptions import DefaultBackoffException, UserDefinedBackoffException
18
18
  from airbyte_cdk.sources.utils.schema_helpers import ResourceSchemaLoader
19
19
  from pendulum.datetime import DateTime
20
- from requests import HTTPError, codes
20
+ from requests import HTTPError
21
21
  from requests.exceptions import ChunkedEncodingError
22
22
  from source_iterable.slice_generators import AdjustableSliceGenerator, RangeSliceGenerator, StreamSlice
23
23
  from source_iterable.utils import dateutil_parse
@@ -106,7 +106,7 @@ class IterableStream(HttpStream, ABC):
106
106
  if self._slice_retry < 3:
107
107
  return True
108
108
  return False
109
- return super().should_retry(response)
109
+ return response.status_code == 429 or 500 <= response.status_code < 600
110
110
 
111
111
  def read_records(
112
112
  self,
source_iterable/utils.py CHANGED
@@ -4,8 +4,6 @@
4
4
 
5
5
  import dateutil.parser
6
6
  import pendulum
7
- from airbyte_cdk.models import SyncMode
8
- from airbyte_cdk.sources.streams import Stream
9
7
 
10
8
 
11
9
  def dateutil_parse(text):