ingestr 0.13.2__py3-none-any.whl → 0.14.104__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.
Files changed (146) hide show
  1. ingestr/conftest.py +72 -0
  2. ingestr/main.py +134 -87
  3. ingestr/src/adjust/__init__.py +4 -4
  4. ingestr/src/adjust/adjust_helpers.py +7 -3
  5. ingestr/src/airtable/__init__.py +3 -2
  6. ingestr/src/allium/__init__.py +128 -0
  7. ingestr/src/anthropic/__init__.py +277 -0
  8. ingestr/src/anthropic/helpers.py +525 -0
  9. ingestr/src/applovin/__init__.py +262 -0
  10. ingestr/src/applovin_max/__init__.py +117 -0
  11. ingestr/src/appsflyer/__init__.py +325 -0
  12. ingestr/src/appsflyer/client.py +49 -45
  13. ingestr/src/appstore/__init__.py +1 -0
  14. ingestr/src/arrow/__init__.py +9 -1
  15. ingestr/src/asana_source/__init__.py +1 -1
  16. ingestr/src/attio/__init__.py +102 -0
  17. ingestr/src/attio/helpers.py +65 -0
  18. ingestr/src/blob.py +38 -11
  19. ingestr/src/buildinfo.py +1 -0
  20. ingestr/src/chess/__init__.py +1 -1
  21. ingestr/src/clickup/__init__.py +85 -0
  22. ingestr/src/clickup/helpers.py +47 -0
  23. ingestr/src/collector/spinner.py +43 -0
  24. ingestr/src/couchbase_source/__init__.py +118 -0
  25. ingestr/src/couchbase_source/helpers.py +135 -0
  26. ingestr/src/cursor/__init__.py +83 -0
  27. ingestr/src/cursor/helpers.py +188 -0
  28. ingestr/src/destinations.py +520 -33
  29. ingestr/src/docebo/__init__.py +589 -0
  30. ingestr/src/docebo/client.py +435 -0
  31. ingestr/src/docebo/helpers.py +97 -0
  32. ingestr/src/elasticsearch/__init__.py +80 -0
  33. ingestr/src/elasticsearch/helpers.py +138 -0
  34. ingestr/src/errors.py +8 -0
  35. ingestr/src/facebook_ads/__init__.py +47 -28
  36. ingestr/src/facebook_ads/helpers.py +59 -37
  37. ingestr/src/facebook_ads/settings.py +2 -0
  38. ingestr/src/facebook_ads/utils.py +39 -0
  39. ingestr/src/factory.py +116 -2
  40. ingestr/src/filesystem/__init__.py +8 -3
  41. ingestr/src/filters.py +46 -3
  42. ingestr/src/fluxx/__init__.py +9906 -0
  43. ingestr/src/fluxx/helpers.py +209 -0
  44. ingestr/src/frankfurter/__init__.py +157 -0
  45. ingestr/src/frankfurter/helpers.py +48 -0
  46. ingestr/src/freshdesk/__init__.py +89 -0
  47. ingestr/src/freshdesk/freshdesk_client.py +137 -0
  48. ingestr/src/freshdesk/settings.py +9 -0
  49. ingestr/src/fundraiseup/__init__.py +95 -0
  50. ingestr/src/fundraiseup/client.py +81 -0
  51. ingestr/src/github/__init__.py +41 -6
  52. ingestr/src/github/helpers.py +5 -5
  53. ingestr/src/google_analytics/__init__.py +22 -4
  54. ingestr/src/google_analytics/helpers.py +124 -6
  55. ingestr/src/google_sheets/__init__.py +4 -4
  56. ingestr/src/google_sheets/helpers/data_processing.py +2 -2
  57. ingestr/src/hostaway/__init__.py +302 -0
  58. ingestr/src/hostaway/client.py +288 -0
  59. ingestr/src/http/__init__.py +35 -0
  60. ingestr/src/http/readers.py +114 -0
  61. ingestr/src/http_client.py +24 -0
  62. ingestr/src/hubspot/__init__.py +66 -23
  63. ingestr/src/hubspot/helpers.py +52 -22
  64. ingestr/src/hubspot/settings.py +14 -7
  65. ingestr/src/influxdb/__init__.py +46 -0
  66. ingestr/src/influxdb/client.py +34 -0
  67. ingestr/src/intercom/__init__.py +142 -0
  68. ingestr/src/intercom/helpers.py +674 -0
  69. ingestr/src/intercom/settings.py +279 -0
  70. ingestr/src/isoc_pulse/__init__.py +159 -0
  71. ingestr/src/jira_source/__init__.py +340 -0
  72. ingestr/src/jira_source/helpers.py +439 -0
  73. ingestr/src/jira_source/settings.py +170 -0
  74. ingestr/src/kafka/__init__.py +4 -1
  75. ingestr/src/kinesis/__init__.py +139 -0
  76. ingestr/src/kinesis/helpers.py +82 -0
  77. ingestr/src/klaviyo/{_init_.py → __init__.py} +5 -6
  78. ingestr/src/linear/__init__.py +634 -0
  79. ingestr/src/linear/helpers.py +111 -0
  80. ingestr/src/linkedin_ads/helpers.py +0 -1
  81. ingestr/src/loader.py +69 -0
  82. ingestr/src/mailchimp/__init__.py +126 -0
  83. ingestr/src/mailchimp/helpers.py +226 -0
  84. ingestr/src/mailchimp/settings.py +164 -0
  85. ingestr/src/masking.py +344 -0
  86. ingestr/src/mixpanel/__init__.py +62 -0
  87. ingestr/src/mixpanel/client.py +99 -0
  88. ingestr/src/monday/__init__.py +246 -0
  89. ingestr/src/monday/helpers.py +392 -0
  90. ingestr/src/monday/settings.py +328 -0
  91. ingestr/src/mongodb/__init__.py +72 -8
  92. ingestr/src/mongodb/helpers.py +915 -38
  93. ingestr/src/partition.py +32 -0
  94. ingestr/src/personio/__init__.py +331 -0
  95. ingestr/src/personio/helpers.py +86 -0
  96. ingestr/src/phantombuster/__init__.py +65 -0
  97. ingestr/src/phantombuster/client.py +87 -0
  98. ingestr/src/pinterest/__init__.py +82 -0
  99. ingestr/src/pipedrive/__init__.py +198 -0
  100. ingestr/src/pipedrive/helpers/__init__.py +23 -0
  101. ingestr/src/pipedrive/helpers/custom_fields_munger.py +102 -0
  102. ingestr/src/pipedrive/helpers/pages.py +115 -0
  103. ingestr/src/pipedrive/settings.py +27 -0
  104. ingestr/src/pipedrive/typing.py +3 -0
  105. ingestr/src/plusvibeai/__init__.py +335 -0
  106. ingestr/src/plusvibeai/helpers.py +544 -0
  107. ingestr/src/plusvibeai/settings.py +252 -0
  108. ingestr/src/quickbooks/__init__.py +117 -0
  109. ingestr/src/resource.py +40 -0
  110. ingestr/src/revenuecat/__init__.py +83 -0
  111. ingestr/src/revenuecat/helpers.py +237 -0
  112. ingestr/src/salesforce/__init__.py +156 -0
  113. ingestr/src/salesforce/helpers.py +64 -0
  114. ingestr/src/shopify/__init__.py +1 -17
  115. ingestr/src/smartsheets/__init__.py +82 -0
  116. ingestr/src/snapchat_ads/__init__.py +489 -0
  117. ingestr/src/snapchat_ads/client.py +72 -0
  118. ingestr/src/snapchat_ads/helpers.py +535 -0
  119. ingestr/src/socrata_source/__init__.py +83 -0
  120. ingestr/src/socrata_source/helpers.py +85 -0
  121. ingestr/src/socrata_source/settings.py +8 -0
  122. ingestr/src/solidgate/__init__.py +219 -0
  123. ingestr/src/solidgate/helpers.py +154 -0
  124. ingestr/src/sources.py +3132 -212
  125. ingestr/src/stripe_analytics/__init__.py +49 -21
  126. ingestr/src/stripe_analytics/helpers.py +286 -1
  127. ingestr/src/stripe_analytics/settings.py +62 -10
  128. ingestr/src/telemetry/event.py +10 -9
  129. ingestr/src/tiktok_ads/__init__.py +12 -6
  130. ingestr/src/tiktok_ads/tiktok_helpers.py +0 -1
  131. ingestr/src/trustpilot/__init__.py +48 -0
  132. ingestr/src/trustpilot/client.py +48 -0
  133. ingestr/src/version.py +6 -1
  134. ingestr/src/wise/__init__.py +68 -0
  135. ingestr/src/wise/client.py +63 -0
  136. ingestr/src/zoom/__init__.py +99 -0
  137. ingestr/src/zoom/helpers.py +102 -0
  138. ingestr/tests/unit/test_smartsheets.py +133 -0
  139. ingestr-0.14.104.dist-info/METADATA +563 -0
  140. ingestr-0.14.104.dist-info/RECORD +203 -0
  141. ingestr/src/appsflyer/_init_.py +0 -24
  142. ingestr-0.13.2.dist-info/METADATA +0 -302
  143. ingestr-0.13.2.dist-info/RECORD +0 -107
  144. {ingestr-0.13.2.dist-info → ingestr-0.14.104.dist-info}/WHEEL +0 -0
  145. {ingestr-0.13.2.dist-info → ingestr-0.14.104.dist-info}/entry_points.txt +0 -0
  146. {ingestr-0.13.2.dist-info → ingestr-0.14.104.dist-info}/licenses/LICENSE.md +0 -0
@@ -0,0 +1,335 @@
1
+ """
2
+ This source provides data extraction from PlusVibeAI via the REST API.
3
+
4
+ It defines functions to fetch data from different parts of PlusVibeAI including
5
+ campaigns and other marketing analytics data.
6
+ """
7
+
8
+ from typing import Any, Iterable, Optional
9
+
10
+ import dlt
11
+ from dlt.common.typing import TDataItem
12
+
13
+ from .helpers import get_client
14
+ from .settings import DEFAULT_PAGE_SIZE, DEFAULT_START_DATE
15
+
16
+
17
+ @dlt.source
18
+ def plusvibeai_source() -> Any:
19
+ """
20
+ The main function that runs all the other functions to fetch data from PlusVibeAI.
21
+
22
+ Returns:
23
+ Sequence[DltResource]: A sequence of DltResource objects containing the fetched data.
24
+ """
25
+ return [
26
+ campaigns,
27
+ leads,
28
+ email_accounts,
29
+ emails,
30
+ blocklist,
31
+ webhooks,
32
+ tags,
33
+ ]
34
+
35
+
36
+ @dlt.resource(
37
+ write_disposition="merge",
38
+ primary_key="id",
39
+ max_table_nesting=0, # Keep nested objects (schedule, sequences) as JSON columns
40
+ )
41
+ def campaigns(
42
+ api_key: str = dlt.secrets.value,
43
+ workspace_id: str = dlt.secrets.value,
44
+ base_url: str = "https://api.plusvibe.ai",
45
+ max_results: Optional[int] = None,
46
+ updated: dlt.sources.incremental[str] = dlt.sources.incremental(
47
+ "modified_at", # PlusVibeAI uses modified_at for updates
48
+ initial_value=DEFAULT_START_DATE,
49
+ range_end="closed",
50
+ range_start="closed",
51
+ ),
52
+ ) -> Iterable[TDataItem]:
53
+ """
54
+ Fetches campaigns from PlusVibeAI.
55
+
56
+ Args:
57
+ api_key (str): API key for authentication (get from https://app.plusvibe.ai/v2/settings/api-access/)
58
+ workspace_id (str): Workspace ID to access
59
+ base_url (str): PlusVibeAI API base URL
60
+ max_results (int): Maximum number of results to return
61
+ updated (str): The date from which to fetch updated campaigns
62
+
63
+ Yields:
64
+ dict: The campaign data with nested objects (schedule, sequences, etc.) as JSON.
65
+ """
66
+ client = get_client(api_key, workspace_id, base_url)
67
+
68
+ for campaign in client.get_campaigns(
69
+ page_size=DEFAULT_PAGE_SIZE, max_results=max_results
70
+ ):
71
+ # Apply incremental filter if needed
72
+ if updated.start_value:
73
+ campaign_updated = campaign.get("modified_at")
74
+ if campaign_updated and campaign_updated < updated.start_value:
75
+ continue
76
+
77
+ yield campaign
78
+
79
+
80
+ @dlt.resource(
81
+ write_disposition="merge",
82
+ primary_key="_id",
83
+ max_table_nesting=0,
84
+ )
85
+ def leads(
86
+ api_key: str = dlt.secrets.value,
87
+ workspace_id: str = dlt.secrets.value,
88
+ base_url: str = "https://api.plusvibe.ai",
89
+ max_results: Optional[int] = None,
90
+ updated: dlt.sources.incremental[str] = dlt.sources.incremental(
91
+ "modified_at",
92
+ initial_value=DEFAULT_START_DATE,
93
+ range_end="closed",
94
+ range_start="closed",
95
+ ),
96
+ ) -> Iterable[TDataItem]:
97
+ """
98
+ Fetches leads from PlusVibeAI.
99
+
100
+ Args:
101
+ api_key (str): API key for authentication
102
+ workspace_id (str): Workspace ID to access
103
+ base_url (str): PlusVibeAI API base URL
104
+ max_results (int): Maximum number of results to return
105
+ updated (str): The date from which to fetch updated leads
106
+
107
+ Yields:
108
+ dict: The lead data.
109
+ """
110
+ client = get_client(api_key, workspace_id, base_url)
111
+
112
+ for lead in client.get_leads(page_size=DEFAULT_PAGE_SIZE, max_results=max_results):
113
+ # Apply incremental filter if needed
114
+ if updated.start_value:
115
+ lead_updated = lead.get("modified_at")
116
+ if lead_updated and lead_updated < updated.start_value:
117
+ continue
118
+
119
+ yield lead
120
+
121
+
122
+ @dlt.resource(
123
+ write_disposition="merge",
124
+ primary_key="_id",
125
+ max_table_nesting=0,
126
+ )
127
+ def email_accounts(
128
+ api_key: str = dlt.secrets.value,
129
+ workspace_id: str = dlt.secrets.value,
130
+ base_url: str = "https://api.plusvibe.ai",
131
+ max_results: Optional[int] = None,
132
+ updated: dlt.sources.incremental[str] = dlt.sources.incremental(
133
+ "timestamp_updated",
134
+ initial_value=DEFAULT_START_DATE,
135
+ range_end="closed",
136
+ range_start="closed",
137
+ ),
138
+ ) -> Iterable[TDataItem]:
139
+ """
140
+ Fetches email accounts from PlusVibeAI.
141
+
142
+ Args:
143
+ api_key (str): API key for authentication
144
+ workspace_id (str): Workspace ID to access
145
+ base_url (str): PlusVibeAI API base URL
146
+ max_results (int): Maximum number of results to return
147
+ updated (str): The date from which to fetch updated email accounts
148
+
149
+ Yields:
150
+ dict: The email account data.
151
+ """
152
+ client = get_client(api_key, workspace_id, base_url)
153
+
154
+ for account in client.get_email_accounts(
155
+ page_size=DEFAULT_PAGE_SIZE, max_results=max_results
156
+ ):
157
+ # Apply incremental filter if needed
158
+ if updated.start_value:
159
+ account_updated = account.get("timestamp_updated")
160
+ if account_updated and account_updated < updated.start_value:
161
+ continue
162
+
163
+ yield account
164
+
165
+
166
+ @dlt.resource(
167
+ write_disposition="merge",
168
+ primary_key="id",
169
+ max_table_nesting=0,
170
+ )
171
+ def emails(
172
+ api_key: str = dlt.secrets.value,
173
+ workspace_id: str = dlt.secrets.value,
174
+ base_url: str = "https://api.plusvibe.ai",
175
+ max_results: Optional[int] = None,
176
+ updated: dlt.sources.incremental[str] = dlt.sources.incremental(
177
+ "timestamp_created",
178
+ initial_value=DEFAULT_START_DATE,
179
+ range_end="closed",
180
+ range_start="closed",
181
+ ),
182
+ ) -> Iterable[TDataItem]:
183
+ """
184
+ Fetches emails from PlusVibeAI.
185
+
186
+ Args:
187
+ api_key (str): API key for authentication
188
+ workspace_id (str): Workspace ID to access
189
+ base_url (str): PlusVibeAI API base URL
190
+ max_results (int): Maximum number of results to return
191
+ updated (str): The date from which to fetch emails
192
+
193
+ Yields:
194
+ dict: The email data.
195
+ """
196
+ client = get_client(api_key, workspace_id, base_url)
197
+
198
+ for email in client.get_emails(max_results=max_results):
199
+ # Apply incremental filter if needed
200
+ if updated.start_value:
201
+ email_created = email.get("timestamp_created")
202
+ if email_created and email_created < updated.start_value:
203
+ continue
204
+
205
+ yield email
206
+
207
+
208
+ @dlt.resource(
209
+ write_disposition="merge",
210
+ primary_key="_id",
211
+ max_table_nesting=0,
212
+ )
213
+ def blocklist(
214
+ api_key: str = dlt.secrets.value,
215
+ workspace_id: str = dlt.secrets.value,
216
+ base_url: str = "https://api.plusvibe.ai",
217
+ max_results: Optional[int] = None,
218
+ updated: dlt.sources.incremental[str] = dlt.sources.incremental(
219
+ "created_at",
220
+ initial_value=DEFAULT_START_DATE,
221
+ range_end="closed",
222
+ range_start="closed",
223
+ ),
224
+ ) -> Iterable[TDataItem]:
225
+ """
226
+ Fetches blocklist entries from PlusVibeAI.
227
+
228
+ Args:
229
+ api_key (str): API key for authentication
230
+ workspace_id (str): Workspace ID to access
231
+ base_url (str): PlusVibeAI API base URL
232
+ max_results (int): Maximum number of results to return
233
+ updated (str): The date from which to fetch blocklist entries
234
+
235
+ Yields:
236
+ dict: The blocklist entry data.
237
+ """
238
+ client = get_client(api_key, workspace_id, base_url)
239
+
240
+ for entry in client.get_blocklist(
241
+ page_size=DEFAULT_PAGE_SIZE, max_results=max_results
242
+ ):
243
+ # Apply incremental filter if needed
244
+ if updated.start_value:
245
+ entry_created = entry.get("created_at")
246
+ if entry_created and entry_created < updated.start_value:
247
+ continue
248
+
249
+ yield entry
250
+
251
+
252
+ @dlt.resource(
253
+ write_disposition="merge",
254
+ primary_key="_id",
255
+ max_table_nesting=0,
256
+ )
257
+ def webhooks(
258
+ api_key: str = dlt.secrets.value,
259
+ workspace_id: str = dlt.secrets.value,
260
+ base_url: str = "https://api.plusvibe.ai",
261
+ max_results: Optional[int] = None,
262
+ updated: dlt.sources.incremental[str] = dlt.sources.incremental(
263
+ "modified_at",
264
+ initial_value=DEFAULT_START_DATE,
265
+ range_end="closed",
266
+ range_start="closed",
267
+ ),
268
+ ) -> Iterable[TDataItem]:
269
+ """
270
+ Fetches webhooks from PlusVibeAI.
271
+
272
+ Args:
273
+ api_key (str): API key for authentication
274
+ workspace_id (str): Workspace ID to access
275
+ base_url (str): PlusVibeAI API base URL
276
+ max_results (int): Maximum number of results to return
277
+ updated (str): The date from which to fetch updated webhooks
278
+
279
+ Yields:
280
+ dict: The webhook data.
281
+ """
282
+ client = get_client(api_key, workspace_id, base_url)
283
+
284
+ for webhook in client.get_webhooks(
285
+ page_size=DEFAULT_PAGE_SIZE, max_results=max_results
286
+ ):
287
+ # Apply incremental filter if needed
288
+ if updated.start_value:
289
+ webhook_updated = webhook.get("modified_at")
290
+ if webhook_updated and webhook_updated < updated.start_value:
291
+ continue
292
+
293
+ yield webhook
294
+
295
+
296
+ @dlt.resource(
297
+ write_disposition="merge",
298
+ primary_key="_id",
299
+ max_table_nesting=0,
300
+ )
301
+ def tags(
302
+ api_key: str = dlt.secrets.value,
303
+ workspace_id: str = dlt.secrets.value,
304
+ base_url: str = "https://api.plusvibe.ai",
305
+ max_results: Optional[int] = None,
306
+ updated: dlt.sources.incremental[str] = dlt.sources.incremental(
307
+ "modified_at",
308
+ initial_value=DEFAULT_START_DATE,
309
+ range_end="closed",
310
+ range_start="closed",
311
+ ),
312
+ ) -> Iterable[TDataItem]:
313
+ """
314
+ Fetches tags from PlusVibeAI.
315
+
316
+ Args:
317
+ api_key (str): API key for authentication
318
+ workspace_id (str): Workspace ID to access
319
+ base_url (str): PlusVibeAI API base URL
320
+ max_results (int): Maximum number of results to return
321
+ updated (str): The date from which to fetch updated tags
322
+
323
+ Yields:
324
+ dict: The tag data.
325
+ """
326
+ client = get_client(api_key, workspace_id, base_url)
327
+
328
+ for tag in client.get_tags(page_size=DEFAULT_PAGE_SIZE, max_results=max_results):
329
+ # Apply incremental filter if needed
330
+ if updated.start_value:
331
+ tag_updated = tag.get("modified_at")
332
+ if tag_updated and tag_updated < updated.start_value:
333
+ continue
334
+
335
+ yield tag