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,166 @@
1
+ """Gorgias source helpers"""
2
+
3
+ import time
4
+ from typing import Any, Iterable, Optional, Tuple
5
+
6
+ from dlt.common.pendulum import pendulum
7
+ from dlt.common.time import ensure_pendulum_datetime
8
+ from dlt.common.typing import Dict, TDataItems
9
+ from dlt.sources.helpers import requests
10
+ from pyrate_limiter import Duration, Limiter, Rate
11
+ from requests.auth import HTTPBasicAuth
12
+
13
+ RETRY_COUNT = 10
14
+
15
+
16
+ def get_max_datetime_from_datetime_fields(
17
+ item: Dict[str, Any],
18
+ ) -> Tuple[str, Optional[pendulum.DateTime]]:
19
+ """Get the maximum datetime from any field that ends with _datetime"""
20
+
21
+ max_field_name = None
22
+ max_field_value = None
23
+ for field in item:
24
+ if field.endswith("_datetime") and item[field] is not None:
25
+ dt = ensure_pendulum_datetime(item[field])
26
+ if not max_field_name or dt > max_field_value:
27
+ max_field_name = field
28
+ max_field_value = dt
29
+
30
+ return max_field_name, max_field_value
31
+
32
+
33
+ def convert_datetime_fields(item: Dict[str, Any]) -> Dict[str, Any]:
34
+ for field in item:
35
+ if field.endswith("_datetime") and item[field] is not None:
36
+ item[field] = ensure_pendulum_datetime(item[field])
37
+
38
+ if "updated_datetime" not in item:
39
+ _, max_datetime = get_max_datetime_from_datetime_fields(item)
40
+ item["updated_datetime"] = max_datetime
41
+
42
+ return item
43
+
44
+
45
+ def find_latest_timestamp_from_page(
46
+ items: list[Dict[str, Any]],
47
+ ) -> Optional[Dict[str, Any]]:
48
+ latest_time = None
49
+ for item in items:
50
+ _, max_field_value = get_max_datetime_from_datetime_fields(item)
51
+ if not latest_time or ensure_pendulum_datetime(max_field_value) > latest_time:
52
+ latest_time = max_field_value
53
+
54
+ return latest_time
55
+
56
+
57
+ class GorgiasApi:
58
+ """
59
+ A Gorgias API client that can be used to get pages of data from Gorgias.
60
+ """
61
+
62
+ def __init__(
63
+ self,
64
+ domain: str,
65
+ email: str,
66
+ api_key: str,
67
+ ) -> None:
68
+ """
69
+ Args:
70
+ domain: The domain of your Gorgias account.
71
+ email: The email associated with your Gorgias account.
72
+ api_key: The API key for accessing the Gorgias API.
73
+ """
74
+ self.domain = domain
75
+ self.email = email
76
+ self.api_key = api_key
77
+
78
+ def get_pages(
79
+ self,
80
+ resource: str,
81
+ params: Optional[Dict[str, Any]] = None,
82
+ start_date: Optional[str] = None,
83
+ end_date: Optional[str] = None,
84
+ ) -> Iterable[TDataItems]:
85
+ """Get all pages from Gorgias using requests.
86
+ Iterates through all pages and yield each page items.
87
+
88
+ Args:
89
+ resource: The resource to get pages for (e.g. products, orders, customers).
90
+ params: Query params to include in the request.
91
+
92
+ Yields:
93
+ List of data items from the page
94
+ """
95
+ url = f"https://{self.domain}.gorgias.com/api/{resource}"
96
+ rate = Rate(2, Duration.SECOND)
97
+ limiter = Limiter(rate, raise_when_fail=False)
98
+
99
+ start_date_obj = ensure_pendulum_datetime(start_date) if start_date else None
100
+
101
+ if not params:
102
+ params = {}
103
+
104
+ params["limit"] = 100
105
+ if "order_by" not in params:
106
+ params["order_by"] = "updated_datetime:desc"
107
+
108
+ while True:
109
+ limiter.try_acquire(f"gorgias-{self.domain}")
110
+
111
+ # this is to retry a back-off if we get a 429
112
+ for i in range(RETRY_COUNT):
113
+ try:
114
+ response = requests.get(
115
+ url, params=params, auth=HTTPBasicAuth(self.email, self.api_key)
116
+ )
117
+ except Exception as e:
118
+ retry_after = int(response.headers.get("Retry-After", 10))
119
+ print(
120
+ f"Got an error from Gorgias API, retrying after {retry_after} seconds",
121
+ e,
122
+ )
123
+ time.sleep(retry_after)
124
+ continue
125
+
126
+ break
127
+
128
+ if len(response.json()["data"]) == 0:
129
+ break
130
+
131
+ json = response.json()
132
+
133
+ items = self.__filter_items_in_range(json["data"], start_date, end_date)
134
+ if len(items) > 0:
135
+ yield items
136
+
137
+ # if there is no cursor, yield the items first and then break the loop
138
+ cursor = json.get("meta", {}).get("next_cursor")
139
+ params["cursor"] = cursor
140
+ if not cursor:
141
+ break
142
+
143
+ if start_date_obj:
144
+ max_datetime = find_latest_timestamp_from_page(json["data"])
145
+ if start_date_obj > ensure_pendulum_datetime(max_datetime):
146
+ break
147
+
148
+ def __filter_items_in_range(
149
+ self,
150
+ items: list[Dict[str, Any]],
151
+ start_date: Optional[str],
152
+ end_date: Optional[str],
153
+ ) -> list[Dict[str, Any]]:
154
+ start_date_obj = ensure_pendulum_datetime(start_date) if start_date else None
155
+ end_date_obj = ensure_pendulum_datetime(end_date) if end_date else None
156
+
157
+ filtered = []
158
+ for item in items:
159
+ converted_item = convert_datetime_fields(item)
160
+ if start_date_obj and item["updated_datetime"] < start_date_obj:
161
+ continue
162
+ if end_date_obj and item["updated_datetime"] > end_date_obj:
163
+ continue
164
+ filtered.append(converted_item)
165
+
166
+ return filtered
@@ -0,0 +1,302 @@
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 HostawayClient
9
+
10
+
11
+ @dlt.source(max_table_nesting=0)
12
+ def hostaway_source(
13
+ api_key: str,
14
+ start_date: pendulum.DateTime,
15
+ end_date: pendulum.DateTime | None = None,
16
+ ) -> Iterable[DltResource]:
17
+ """
18
+ Hostaway API source for fetching listings and fee settings data.
19
+
20
+ Args:
21
+ api_key: Hostaway API key for Bearer token authentication
22
+ start_date: Start date for incremental loading
23
+ end_date: End date for incremental loading (defaults to current time)
24
+
25
+ Returns:
26
+ Iterable[DltResource]: DLT resources for listings and/or fee settings
27
+ """
28
+
29
+ client = HostawayClient(api_key)
30
+
31
+ @dlt.resource(
32
+ write_disposition="merge",
33
+ name="listings",
34
+ primary_key="id",
35
+ )
36
+ def listings(
37
+ datetime=dlt.sources.incremental(
38
+ "latestActivityOn",
39
+ initial_value=start_date,
40
+ end_value=end_date,
41
+ range_end="closed",
42
+ range_start="closed",
43
+ ),
44
+ ) -> Iterable[TDataItem]:
45
+ """
46
+ Fetch listings from Hostaway API with incremental loading.
47
+ Uses latestActivityOn field as the incremental cursor.
48
+ """
49
+ start_dt = datetime.last_value
50
+ end_dt = (
51
+ datetime.end_value
52
+ if datetime.end_value is not None
53
+ else pendulum.now(tz="UTC")
54
+ )
55
+
56
+ yield from client.fetch_listings(start_dt, end_dt)
57
+
58
+ @dlt.resource(
59
+ write_disposition="merge",
60
+ name="listing_fee_settings",
61
+ primary_key="id",
62
+ )
63
+ def listing_fee_settings(
64
+ datetime=dlt.sources.incremental(
65
+ "updatedOn",
66
+ initial_value=start_date,
67
+ end_value=end_date,
68
+ range_end="closed",
69
+ range_start="closed",
70
+ ),
71
+ ) -> Iterable[TDataItem]:
72
+ """
73
+ Fetch listing fee settings from Hostaway API with incremental loading.
74
+ Uses updatedOn field as the incremental cursor.
75
+ """
76
+ start_dt = datetime.last_value
77
+ end_dt = (
78
+ datetime.end_value
79
+ if datetime.end_value is not None
80
+ else pendulum.now(tz="UTC")
81
+ )
82
+
83
+ yield from client.fetch_all_listing_fee_settings(start_dt, end_dt)
84
+
85
+ @dlt.resource(
86
+ write_disposition="replace",
87
+ name="listing_agreements",
88
+ )
89
+ def listing_agreements() -> Iterable[TDataItem]:
90
+ """
91
+ Fetch listing agreements from Hostaway API.
92
+
93
+ Note: Uses replace mode, so no incremental loading.
94
+ """
95
+ very_old_date = pendulum.datetime(1970, 1, 1, tz="UTC")
96
+ now = pendulum.now(tz="UTC")
97
+ yield from client.fetch_all_listing_agreements(very_old_date, now)
98
+
99
+ @dlt.resource(
100
+ write_disposition="replace",
101
+ name="listing_pricing_settings",
102
+ )
103
+ def listing_pricing_settings() -> Iterable[TDataItem]:
104
+ """
105
+ Fetch listing pricing settings from Hostaway API.
106
+
107
+ Note: Uses replace mode, so no incremental loading.
108
+ """
109
+ very_old_date = pendulum.datetime(1970, 1, 1, tz="UTC")
110
+ now = pendulum.now(tz="UTC")
111
+ yield from client.fetch_all_listing_pricing_settings(very_old_date, now)
112
+
113
+ @dlt.resource(
114
+ write_disposition="replace",
115
+ name="cancellation_policies",
116
+ )
117
+ def cancellation_policies() -> Iterable[TDataItem]:
118
+ yield from client.fetch_cancellation_policies()
119
+
120
+ @dlt.resource(
121
+ write_disposition="replace",
122
+ name="cancellation_policies_airbnb",
123
+ )
124
+ def cancellation_policies_airbnb() -> Iterable[TDataItem]:
125
+ yield from client.fetch_cancellation_policies_airbnb()
126
+
127
+ @dlt.resource(
128
+ write_disposition="replace",
129
+ name="cancellation_policies_marriott",
130
+ )
131
+ def cancellation_policies_marriott() -> Iterable[TDataItem]:
132
+ yield from client.fetch_cancellation_policies_marriott()
133
+
134
+ @dlt.resource(
135
+ write_disposition="replace",
136
+ name="cancellation_policies_vrbo",
137
+ )
138
+ def cancellation_policies_vrbo() -> Iterable[TDataItem]:
139
+ yield from client.fetch_cancellation_policies_vrbo()
140
+
141
+ @dlt.resource(
142
+ write_disposition="replace",
143
+ name="reservations",
144
+ selected=False,
145
+ )
146
+ def reservations() -> Iterable[TDataItem]:
147
+ yield from client.fetch_reservations()
148
+
149
+ @dlt.transformer(
150
+ data_from=reservations,
151
+ write_disposition="replace",
152
+ name="finance_fields",
153
+ )
154
+ def finance_fields(reservation_item: TDataItem) -> Iterable[TDataItem]:
155
+ @dlt.defer
156
+ def _get_finance_field(res_id):
157
+ return list(client.fetch_finance_field(res_id))
158
+
159
+ reservation_id_val = reservation_item.get("id")
160
+ if reservation_id_val:
161
+ yield _get_finance_field(reservation_id_val)
162
+
163
+ @dlt.resource(
164
+ write_disposition="replace",
165
+ name="reservation_payment_methods",
166
+ )
167
+ def reservation_payment_methods() -> Iterable[TDataItem]:
168
+ yield from client.fetch_reservation_payment_methods()
169
+
170
+ @dlt.transformer(
171
+ data_from=reservations,
172
+ write_disposition="replace",
173
+ name="reservation_rental_agreements",
174
+ )
175
+ def reservation_rental_agreements(
176
+ reservation_item: TDataItem,
177
+ ) -> Iterable[TDataItem]:
178
+ @dlt.defer
179
+ def _get_rental_agreement(res_id):
180
+ return list(client.fetch_reservation_rental_agreement(res_id))
181
+
182
+ reservation_id = reservation_item.get("id")
183
+ if reservation_id:
184
+ yield _get_rental_agreement(reservation_id)
185
+
186
+ @dlt.transformer(
187
+ data_from=listings,
188
+ write_disposition="replace",
189
+ name="listing_calendars",
190
+ )
191
+ def listing_calendars(listing_item: TDataItem) -> Iterable[TDataItem]:
192
+ @dlt.defer
193
+ def _get_calendar(lst_id):
194
+ return list(client.fetch_listing_calendar(lst_id))
195
+
196
+ listing_id_val = listing_item.get("id")
197
+ if listing_id_val:
198
+ yield _get_calendar(listing_id_val)
199
+
200
+ @dlt.resource(
201
+ write_disposition="replace",
202
+ name="conversations",
203
+ )
204
+ def conversations() -> Iterable[TDataItem]:
205
+ yield from client.fetch_conversations()
206
+
207
+ @dlt.resource(
208
+ write_disposition="replace",
209
+ name="message_templates",
210
+ )
211
+ def message_templates() -> Iterable[TDataItem]:
212
+ yield from client.fetch_message_templates()
213
+
214
+ @dlt.resource(
215
+ write_disposition="replace",
216
+ name="bed_types",
217
+ )
218
+ def bed_types() -> Iterable[TDataItem]:
219
+ yield from client.fetch_bed_types()
220
+
221
+ @dlt.resource(
222
+ write_disposition="replace",
223
+ name="property_types",
224
+ )
225
+ def property_types() -> Iterable[TDataItem]:
226
+ yield from client.fetch_property_types()
227
+
228
+ @dlt.resource(
229
+ write_disposition="replace",
230
+ name="countries",
231
+ )
232
+ def countries() -> Iterable[TDataItem]:
233
+ yield from client.fetch_countries()
234
+
235
+ @dlt.resource(
236
+ write_disposition="replace",
237
+ name="account_tax_settings",
238
+ )
239
+ def account_tax_settings() -> Iterable[TDataItem]:
240
+ yield from client.fetch_account_tax_settings()
241
+
242
+ @dlt.resource(
243
+ write_disposition="replace",
244
+ name="user_groups",
245
+ )
246
+ def user_groups() -> Iterable[TDataItem]:
247
+ yield from client.fetch_user_groups()
248
+
249
+ @dlt.resource(
250
+ write_disposition="replace",
251
+ name="guest_payment_charges",
252
+ )
253
+ def guest_payment_charges() -> Iterable[TDataItem]:
254
+ yield from client.fetch_guest_payment_charges()
255
+
256
+ @dlt.resource(
257
+ write_disposition="replace",
258
+ name="coupons",
259
+ )
260
+ def coupons() -> Iterable[TDataItem]:
261
+ yield from client.fetch_coupons()
262
+
263
+ @dlt.resource(
264
+ write_disposition="replace",
265
+ name="webhook_reservations",
266
+ )
267
+ def webhook_reservations() -> Iterable[TDataItem]:
268
+ yield from client.fetch_webhook_reservations()
269
+
270
+ @dlt.resource(
271
+ write_disposition="replace",
272
+ name="tasks",
273
+ )
274
+ def tasks() -> Iterable[TDataItem]:
275
+ yield from client.fetch_tasks()
276
+
277
+ return (
278
+ listings,
279
+ listing_fee_settings,
280
+ listing_agreements,
281
+ listing_pricing_settings,
282
+ cancellation_policies,
283
+ cancellation_policies_airbnb,
284
+ cancellation_policies_marriott,
285
+ cancellation_policies_vrbo,
286
+ reservations,
287
+ finance_fields,
288
+ reservation_payment_methods,
289
+ reservation_rental_agreements,
290
+ listing_calendars,
291
+ conversations,
292
+ message_templates,
293
+ bed_types,
294
+ property_types,
295
+ countries,
296
+ account_tax_settings,
297
+ user_groups,
298
+ guest_payment_charges,
299
+ coupons,
300
+ webhook_reservations,
301
+ tasks,
302
+ )