omniload 0.0.0.dev0__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 (218) hide show
  1. omniload/conftest.py +72 -0
  2. omniload/main.py +810 -0
  3. omniload/src/.gitignore +10 -0
  4. omniload/src/adjust/__init__.py +108 -0
  5. omniload/src/adjust/adjust_helpers.py +122 -0
  6. omniload/src/airtable/__init__.py +84 -0
  7. omniload/src/allium/__init__.py +128 -0
  8. omniload/src/anthropic/__init__.py +277 -0
  9. omniload/src/anthropic/helpers.py +525 -0
  10. omniload/src/applovin/__init__.py +316 -0
  11. omniload/src/applovin_max/__init__.py +117 -0
  12. omniload/src/appsflyer/__init__.py +325 -0
  13. omniload/src/appsflyer/client.py +110 -0
  14. omniload/src/appstore/__init__.py +142 -0
  15. omniload/src/appstore/client.py +126 -0
  16. omniload/src/appstore/errors.py +15 -0
  17. omniload/src/appstore/models.py +117 -0
  18. omniload/src/appstore/resources.py +179 -0
  19. omniload/src/arrow/__init__.py +81 -0
  20. omniload/src/asana_source/__init__.py +281 -0
  21. omniload/src/asana_source/helpers.py +30 -0
  22. omniload/src/asana_source/settings.py +158 -0
  23. omniload/src/attio/__init__.py +102 -0
  24. omniload/src/attio/helpers.py +65 -0
  25. omniload/src/blob.py +95 -0
  26. omniload/src/bruin/__init__.py +76 -0
  27. omniload/src/chess/__init__.py +180 -0
  28. omniload/src/chess/helpers.py +35 -0
  29. omniload/src/chess/settings.py +18 -0
  30. omniload/src/clickup/__init__.py +85 -0
  31. omniload/src/clickup/helpers.py +47 -0
  32. omniload/src/collector/spinner.py +43 -0
  33. omniload/src/couchbase_source/__init__.py +118 -0
  34. omniload/src/couchbase_source/helpers.py +135 -0
  35. omniload/src/cursor/__init__.py +83 -0
  36. omniload/src/cursor/helpers.py +188 -0
  37. omniload/src/customer_io/__init__.py +486 -0
  38. omniload/src/customer_io/helpers.py +530 -0
  39. omniload/src/destinations.py +982 -0
  40. omniload/src/docebo/__init__.py +589 -0
  41. omniload/src/docebo/client.py +435 -0
  42. omniload/src/docebo/helpers.py +97 -0
  43. omniload/src/dune/__init__.py +104 -0
  44. omniload/src/dune/helpers.py +108 -0
  45. omniload/src/dynamodb/__init__.py +86 -0
  46. omniload/src/elasticsearch/__init__.py +80 -0
  47. omniload/src/elasticsearch/helpers.py +141 -0
  48. omniload/src/errors.py +26 -0
  49. omniload/src/facebook_ads/__init__.py +403 -0
  50. omniload/src/facebook_ads/exceptions.py +19 -0
  51. omniload/src/facebook_ads/helpers.py +296 -0
  52. omniload/src/facebook_ads/settings.py +224 -0
  53. omniload/src/facebook_ads/utils.py +53 -0
  54. omniload/src/factory.py +305 -0
  55. omniload/src/filesystem/__init__.py +133 -0
  56. omniload/src/filesystem/helpers.py +114 -0
  57. omniload/src/filesystem/readers.py +187 -0
  58. omniload/src/filters.py +62 -0
  59. omniload/src/fireflies/__init__.py +151 -0
  60. omniload/src/fireflies/helpers.py +753 -0
  61. omniload/src/fluxx/__init__.py +10013 -0
  62. omniload/src/fluxx/helpers.py +233 -0
  63. omniload/src/frankfurter/__init__.py +157 -0
  64. omniload/src/frankfurter/helpers.py +48 -0
  65. omniload/src/freshdesk/__init__.py +103 -0
  66. omniload/src/freshdesk/freshdesk_client.py +151 -0
  67. omniload/src/freshdesk/settings.py +23 -0
  68. omniload/src/fundraiseup/__init__.py +95 -0
  69. omniload/src/fundraiseup/client.py +81 -0
  70. omniload/src/github/__init__.py +202 -0
  71. omniload/src/github/helpers.py +207 -0
  72. omniload/src/github/queries.py +129 -0
  73. omniload/src/github/settings.py +24 -0
  74. omniload/src/google_ads/__init__.py +198 -0
  75. omniload/src/google_ads/field.py +17 -0
  76. omniload/src/google_ads/metrics.py +254 -0
  77. omniload/src/google_ads/predicates.py +37 -0
  78. omniload/src/google_ads/reports.py +411 -0
  79. omniload/src/google_ads/test_google_ads.py +184 -0
  80. omniload/src/google_analytics/__init__.py +144 -0
  81. omniload/src/google_analytics/helpers.py +312 -0
  82. omniload/src/google_sheets/README.md +95 -0
  83. omniload/src/google_sheets/__init__.py +166 -0
  84. omniload/src/google_sheets/helpers/__init__.py +15 -0
  85. omniload/src/google_sheets/helpers/api_calls.py +160 -0
  86. omniload/src/google_sheets/helpers/data_processing.py +316 -0
  87. omniload/src/gorgias/__init__.py +595 -0
  88. omniload/src/gorgias/helpers.py +166 -0
  89. omniload/src/hostaway/__init__.py +302 -0
  90. omniload/src/hostaway/client.py +288 -0
  91. omniload/src/http/__init__.py +38 -0
  92. omniload/src/http/readers.py +146 -0
  93. omniload/src/http_client.py +24 -0
  94. omniload/src/hubspot/__init__.py +800 -0
  95. omniload/src/hubspot/helpers.py +417 -0
  96. omniload/src/hubspot/settings.py +329 -0
  97. omniload/src/indeed/__init__.py +153 -0
  98. omniload/src/indeed/helpers.py +228 -0
  99. omniload/src/influxdb/__init__.py +46 -0
  100. omniload/src/influxdb/client.py +34 -0
  101. omniload/src/intercom/__init__.py +142 -0
  102. omniload/src/intercom/helpers.py +674 -0
  103. omniload/src/intercom/settings.py +279 -0
  104. omniload/src/isoc_pulse/__init__.py +159 -0
  105. omniload/src/jira_source/__init__.py +377 -0
  106. omniload/src/jira_source/helpers.py +510 -0
  107. omniload/src/jira_source/settings.py +184 -0
  108. omniload/src/kafka/__init__.py +120 -0
  109. omniload/src/kafka/helpers.py +241 -0
  110. omniload/src/kinesis/__init__.py +153 -0
  111. omniload/src/kinesis/helpers.py +96 -0
  112. omniload/src/klaviyo/__init__.py +237 -0
  113. omniload/src/klaviyo/client.py +212 -0
  114. omniload/src/klaviyo/helpers.py +19 -0
  115. omniload/src/linear/__init__.py +634 -0
  116. omniload/src/linear/helpers.py +111 -0
  117. omniload/src/linkedin_ads/__init__.py +266 -0
  118. omniload/src/linkedin_ads/dimension_time_enum.py +17 -0
  119. omniload/src/linkedin_ads/helpers.py +246 -0
  120. omniload/src/loader.py +69 -0
  121. omniload/src/mailchimp/__init__.py +126 -0
  122. omniload/src/mailchimp/helpers.py +226 -0
  123. omniload/src/mailchimp/settings.py +164 -0
  124. omniload/src/masking.py +344 -0
  125. omniload/src/mixpanel/__init__.py +62 -0
  126. omniload/src/mixpanel/client.py +104 -0
  127. omniload/src/monday/__init__.py +246 -0
  128. omniload/src/monday/helpers.py +392 -0
  129. omniload/src/monday/settings.py +325 -0
  130. omniload/src/mongodb/__init__.py +281 -0
  131. omniload/src/mongodb/helpers.py +975 -0
  132. omniload/src/notion/__init__.py +69 -0
  133. omniload/src/notion/helpers/__init__.py +14 -0
  134. omniload/src/notion/helpers/client.py +178 -0
  135. omniload/src/notion/helpers/database.py +92 -0
  136. omniload/src/notion/settings.py +17 -0
  137. omniload/src/partition.py +32 -0
  138. omniload/src/personio/__init__.py +345 -0
  139. omniload/src/personio/helpers.py +100 -0
  140. omniload/src/phantombuster/__init__.py +65 -0
  141. omniload/src/phantombuster/client.py +87 -0
  142. omniload/src/pinterest/__init__.py +82 -0
  143. omniload/src/pipedrive/__init__.py +212 -0
  144. omniload/src/pipedrive/helpers/__init__.py +37 -0
  145. omniload/src/pipedrive/helpers/custom_fields_munger.py +116 -0
  146. omniload/src/pipedrive/helpers/pages.py +129 -0
  147. omniload/src/pipedrive/settings.py +41 -0
  148. omniload/src/pipedrive/typing.py +17 -0
  149. omniload/src/plusvibeai/__init__.py +335 -0
  150. omniload/src/plusvibeai/helpers.py +544 -0
  151. omniload/src/plusvibeai/settings.py +252 -0
  152. omniload/src/primer/__init__.py +45 -0
  153. omniload/src/primer/helpers.py +79 -0
  154. omniload/src/quickbooks/__init__.py +117 -0
  155. omniload/src/reddit_ads/__init__.py +183 -0
  156. omniload/src/reddit_ads/helpers.py +232 -0
  157. omniload/src/resource.py +40 -0
  158. omniload/src/revenuecat/__init__.py +83 -0
  159. omniload/src/revenuecat/helpers.py +237 -0
  160. omniload/src/salesforce/__init__.py +170 -0
  161. omniload/src/salesforce/helpers.py +78 -0
  162. omniload/src/shopify/__init__.py +1953 -0
  163. omniload/src/shopify/exceptions.py +17 -0
  164. omniload/src/shopify/helpers.py +202 -0
  165. omniload/src/shopify/settings.py +19 -0
  166. omniload/src/slack/__init__.py +290 -0
  167. omniload/src/slack/helpers.py +218 -0
  168. omniload/src/slack/settings.py +36 -0
  169. omniload/src/smartsheets/__init__.py +82 -0
  170. omniload/src/snapchat_ads/__init__.py +455 -0
  171. omniload/src/snapchat_ads/client.py +72 -0
  172. omniload/src/snapchat_ads/helpers.py +630 -0
  173. omniload/src/snapchat_ads/settings.py +130 -0
  174. omniload/src/socrata_source/__init__.py +83 -0
  175. omniload/src/socrata_source/helpers.py +85 -0
  176. omniload/src/socrata_source/settings.py +8 -0
  177. omniload/src/solidgate/__init__.py +219 -0
  178. omniload/src/solidgate/helpers.py +154 -0
  179. omniload/src/sources.py +5408 -0
  180. omniload/src/sql_database/__init__.py +0 -0
  181. omniload/src/sql_database/callbacks.py +66 -0
  182. omniload/src/stripe_analytics/__init__.py +183 -0
  183. omniload/src/stripe_analytics/helpers.py +386 -0
  184. omniload/src/stripe_analytics/settings.py +80 -0
  185. omniload/src/table_definition.py +15 -0
  186. omniload/src/testdata/fakebqcredentials.json +14 -0
  187. omniload/src/tiktok_ads/__init__.py +150 -0
  188. omniload/src/tiktok_ads/tiktok_helpers.py +130 -0
  189. omniload/src/time.py +11 -0
  190. omniload/src/trustpilot/__init__.py +48 -0
  191. omniload/src/trustpilot/client.py +48 -0
  192. omniload/src/version.py +6 -0
  193. omniload/src/wise/__init__.py +68 -0
  194. omniload/src/wise/client.py +63 -0
  195. omniload/src/zendesk/__init__.py +480 -0
  196. omniload/src/zendesk/helpers/__init__.py +39 -0
  197. omniload/src/zendesk/helpers/api_helpers.py +119 -0
  198. omniload/src/zendesk/helpers/credentials.py +68 -0
  199. omniload/src/zendesk/helpers/talk_api.py +132 -0
  200. omniload/src/zendesk/settings.py +71 -0
  201. omniload/src/zoom/__init__.py +99 -0
  202. omniload/src/zoom/helpers.py +102 -0
  203. omniload/testdata/.gitignore +2 -0
  204. omniload/testdata/create_replace.csv +21 -0
  205. omniload/testdata/delete_insert_expected.csv +6 -0
  206. omniload/testdata/delete_insert_part1.csv +5 -0
  207. omniload/testdata/delete_insert_part2.csv +6 -0
  208. omniload/testdata/merge_expected.csv +5 -0
  209. omniload/testdata/merge_part1.csv +4 -0
  210. omniload/testdata/merge_part2.csv +5 -0
  211. omniload/tests/unit/test_smartsheets.py +133 -0
  212. omniload-0.0.0.dev0.dist-info/METADATA +439 -0
  213. omniload-0.0.0.dev0.dist-info/RECORD +218 -0
  214. omniload-0.0.0.dev0.dist-info/WHEEL +4 -0
  215. omniload-0.0.0.dev0.dist-info/entry_points.txt +2 -0
  216. omniload-0.0.0.dev0.dist-info/licenses/LICENSE.Apache-2.0 +201 -0
  217. omniload-0.0.0.dev0.dist-info/licenses/LICENSE.md +21 -0
  218. omniload-0.0.0.dev0.dist-info/licenses/NOTICE +35 -0
@@ -0,0 +1,46 @@
1
+ from typing import Iterable
2
+
3
+ import dlt
4
+ import pendulum
5
+ from dlt.common.typing import TDataItem
6
+ from dlt.sources import DltResource
7
+
8
+ from .client import InfluxClient
9
+
10
+
11
+ @dlt.source(max_table_nesting=0)
12
+ def influxdb_source(
13
+ measurement: str,
14
+ host: str,
15
+ org: str,
16
+ bucket: str,
17
+ token: str = dlt.secrets.value,
18
+ secure: bool = True,
19
+ start_date: pendulum.DateTime = pendulum.datetime(2024, 1, 1),
20
+ end_date: pendulum.DateTime | None = None,
21
+ ) -> Iterable[DltResource]:
22
+ client = InfluxClient(
23
+ url=host, token=token, org=org, bucket=bucket, verify_ssl=secure
24
+ )
25
+
26
+ @dlt.resource(name=measurement)
27
+ def fetch_table(
28
+ timestamp=dlt.sources.incremental(
29
+ "time",
30
+ initial_value=start_date,
31
+ end_value=end_date,
32
+ range_start="closed",
33
+ range_end="closed",
34
+ ),
35
+ ) -> Iterable[TDataItem]:
36
+ if timestamp.last_value is None:
37
+ start = start_date.isoformat()
38
+ else:
39
+ start = timestamp.last_value.isoformat()
40
+ if timestamp.end_value is None:
41
+ end = pendulum.now().isoformat()
42
+ else:
43
+ end = timestamp.end_value.isoformat()
44
+ yield from client.fetch_measurement(measurement, start, end)
45
+
46
+ return fetch_table
@@ -0,0 +1,34 @@
1
+ from typing import Any, Dict, Iterable
2
+
3
+ from influxdb_client import InfluxDBClient # type: ignore
4
+
5
+
6
+ class InfluxClient:
7
+ def __init__(
8
+ self, url: str, token: str, org: str, bucket: str, verify_ssl: bool = True
9
+ ) -> None:
10
+ self.client = InfluxDBClient(
11
+ url=url, token=token, org=org, verify_ssl=verify_ssl
12
+ )
13
+ self.bucket = bucket
14
+
15
+ def fetch_measurement(
16
+ self, measurement: str, start: str, end: str | None = None
17
+ ) -> Iterable[Dict[str, Any]]:
18
+ query = f'from(bucket: "{self.bucket}") |> range(start: {start}'
19
+ if end:
20
+ query += f", stop: {end}"
21
+ query += f') |> filter(fn: (r) => r["_measurement"] == "{measurement}")'
22
+ query_api = self.client.query_api()
23
+
24
+ for record in query_api.query_stream(query):
25
+ cleaned_record = {}
26
+ exclude_keys = {"result", "table", "_start", "_stop"}
27
+ for key, value in record.values.items():
28
+ if key in exclude_keys:
29
+ continue
30
+ if key.startswith("_"):
31
+ cleaned_record[key[1:]] = value
32
+ else:
33
+ cleaned_record[key] = value
34
+ yield cleaned_record
@@ -0,0 +1,142 @@
1
+ """
2
+ Intercom source implementation for data ingestion.
3
+
4
+ This module provides DLT sources for retrieving data from Intercom API endpoints
5
+ including contacts, companies, conversations, tickets, and more.
6
+ """
7
+
8
+ from typing import Optional, Sequence
9
+
10
+ import dlt
11
+ from dlt.common.time import ensure_pendulum_datetime
12
+ from dlt.common.typing import TAnyDateTime
13
+ from dlt.sources import DltResource, DltSource
14
+
15
+ from .helpers import (
16
+ IntercomAPIClient,
17
+ IntercomCredentialsAccessToken,
18
+ TIntercomCredentials,
19
+ convert_datetime_to_timestamp,
20
+ create_resource_from_config,
21
+ transform_company,
22
+ transform_contact,
23
+ transform_conversation,
24
+ )
25
+ from .helpers import (
26
+ IntercomCredentialsOAuth as IntercomCredentialsOAuth,
27
+ )
28
+ from .settings import (
29
+ DEFAULT_START_DATE,
30
+ RESOURCE_CONFIGS,
31
+ )
32
+
33
+
34
+ @dlt.source(name="intercom", max_table_nesting=0)
35
+ def intercom_source(
36
+ credentials: TIntercomCredentials = dlt.secrets.value,
37
+ start_date: Optional[TAnyDateTime] = DEFAULT_START_DATE,
38
+ end_date: Optional[TAnyDateTime] = None,
39
+ ) -> Sequence[DltResource]:
40
+ """
41
+ A DLT source that retrieves data from Intercom API.
42
+
43
+ This source provides access to various Intercom resources including contacts,
44
+ companies, conversations, tickets, and more. It supports incremental loading
45
+ for resources that track updated timestamps.
46
+
47
+ Args:
48
+ credentials: Intercom API credentials (AccessToken or OAuth).
49
+ Defaults to dlt.secrets.value.
50
+ start_date: The start date for incremental loading.
51
+ Defaults to January 1, 2020.
52
+ end_date: Optional end date for incremental loading.
53
+ If not provided, loads all data from start_date to present.
54
+
55
+ Returns:
56
+ Sequence of DLT resources for different Intercom endpoints.
57
+
58
+ Example:
59
+ >>> source = intercom_source(
60
+ ... credentials=IntercomCredentialsAccessToken(
61
+ ... access_token="your_token",
62
+ ... region="us"
63
+ ... ),
64
+ ... start_date=datetime(2024, 1, 1)
65
+ ... )
66
+ """
67
+ # Initialize API client
68
+ api_client = IntercomAPIClient(credentials)
69
+
70
+ # Convert dates to pendulum and then to unix timestamps for Intercom API
71
+ start_date_obj = ensure_pendulum_datetime(start_date) if start_date else None
72
+ end_date_obj = ensure_pendulum_datetime(end_date) if end_date else None
73
+
74
+ # Convert to unix timestamps for API compatibility
75
+ # Use default start date if none provided
76
+ if not start_date_obj:
77
+ from .settings import DEFAULT_START_DATE
78
+
79
+ start_date_obj = ensure_pendulum_datetime(DEFAULT_START_DATE)
80
+
81
+ start_timestamp = convert_datetime_to_timestamp(start_date_obj)
82
+ end_timestamp = (
83
+ convert_datetime_to_timestamp(end_date_obj) if end_date_obj else None
84
+ )
85
+
86
+ # Transform function mapping
87
+ transform_functions = {
88
+ "transform_contact": transform_contact,
89
+ "transform_company": transform_company,
90
+ "transform_conversation": transform_conversation,
91
+ }
92
+
93
+ # Generate all resources from configuration
94
+ resources = []
95
+ for resource_name, config in RESOURCE_CONFIGS.items():
96
+ resource_func = create_resource_from_config(
97
+ resource_name,
98
+ config,
99
+ api_client,
100
+ start_timestamp,
101
+ end_timestamp,
102
+ transform_functions,
103
+ )
104
+
105
+ # Call the resource function to get the actual resource
106
+ resources.append(resource_func())
107
+
108
+ return resources
109
+
110
+
111
+ def intercom(
112
+ api_key: str,
113
+ region: str = "us",
114
+ start_date: Optional[TAnyDateTime] = DEFAULT_START_DATE,
115
+ end_date: Optional[TAnyDateTime] = None,
116
+ ) -> DltSource:
117
+ """
118
+ Convenience function to create Intercom source with access token.
119
+
120
+ Args:
121
+ api_key: Intercom API access token.
122
+ region: Data region (us, eu, or au). Defaults to "us".
123
+ start_date: Start date for incremental loading.
124
+ end_date: Optional end date for incremental loading.
125
+
126
+ Returns:
127
+ Sequence of DLT resources.
128
+
129
+ Example:
130
+ >>> source = intercom(
131
+ ... api_key="your_access_token",
132
+ ... region="us",
133
+ ... start_date=datetime(2024, 1, 1)
134
+ ... )
135
+ """
136
+ credentials = IntercomCredentialsAccessToken(access_token=api_key, region=region)
137
+
138
+ return intercom_source(
139
+ credentials=credentials,
140
+ start_date=start_date,
141
+ end_date=end_date,
142
+ )