apache-airflow-providers-dbt-cloud 4.4.3rc1__py3-none-any.whl → 4.4.4__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.
Potentially problematic release.
This version of apache-airflow-providers-dbt-cloud might be problematic. Click here for more details.
- airflow/providers/dbt/cloud/__init__.py +1 -1
- airflow/providers/dbt/cloud/hooks/dbt.py +106 -14
- airflow/providers/dbt/cloud/operators/dbt.py +13 -8
- airflow/providers/dbt/cloud/sensors/dbt.py +1 -6
- airflow/providers/dbt/cloud/triggers/dbt.py +5 -1
- airflow/providers/dbt/cloud/version_compat.py +0 -12
- {apache_airflow_providers_dbt_cloud-4.4.3rc1.dist-info → apache_airflow_providers_dbt_cloud-4.4.4.dist-info}/METADATA +21 -10
- apache_airflow_providers_dbt_cloud-4.4.4.dist-info/RECORD +18 -0
- apache_airflow_providers_dbt_cloud-4.4.3rc1.dist-info/RECORD +0 -18
- {apache_airflow_providers_dbt_cloud-4.4.3rc1.dist-info → apache_airflow_providers_dbt_cloud-4.4.4.dist-info}/WHEEL +0 -0
- {apache_airflow_providers_dbt_cloud-4.4.3rc1.dist-info → apache_airflow_providers_dbt_cloud-4.4.4.dist-info}/entry_points.txt +0 -0
|
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
|
|
|
29
29
|
|
|
30
30
|
__all__ = ["__version__"]
|
|
31
31
|
|
|
32
|
-
__version__ = "4.4.
|
|
32
|
+
__version__ = "4.4.4"
|
|
33
33
|
|
|
34
34
|
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
|
|
35
35
|
"2.10.0"
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import asyncio
|
|
20
|
+
import copy
|
|
20
21
|
import json
|
|
21
22
|
import time
|
|
22
23
|
import warnings
|
|
@@ -28,8 +29,10 @@ from typing import TYPE_CHECKING, Any, TypedDict, TypeVar, cast
|
|
|
28
29
|
|
|
29
30
|
import aiohttp
|
|
30
31
|
from asgiref.sync import sync_to_async
|
|
32
|
+
from requests import exceptions as requests_exceptions
|
|
31
33
|
from requests.auth import AuthBase
|
|
32
34
|
from requests.sessions import Session
|
|
35
|
+
from tenacity import AsyncRetrying, RetryCallState, retry_if_exception, stop_after_attempt, wait_exponential
|
|
33
36
|
|
|
34
37
|
from airflow.exceptions import AirflowException
|
|
35
38
|
from airflow.providers.http.hooks.http import HttpHook
|
|
@@ -174,6 +177,10 @@ class DbtCloudHook(HttpHook):
|
|
|
174
177
|
Interact with dbt Cloud using the V2 (V3 if supported) API.
|
|
175
178
|
|
|
176
179
|
:param dbt_cloud_conn_id: The ID of the :ref:`dbt Cloud connection <howto/connection:dbt-cloud>`.
|
|
180
|
+
:param timeout_seconds: Optional. The timeout in seconds for HTTP requests. If not provided, no timeout is applied.
|
|
181
|
+
:param retry_limit: The number of times to retry a request in case of failure.
|
|
182
|
+
:param retry_delay: The delay in seconds between retries.
|
|
183
|
+
:param retry_args: A dictionary of arguments to pass to the `tenacity.retry` decorator.
|
|
177
184
|
"""
|
|
178
185
|
|
|
179
186
|
conn_name_attr = "dbt_cloud_conn_id"
|
|
@@ -193,9 +200,39 @@ class DbtCloudHook(HttpHook):
|
|
|
193
200
|
},
|
|
194
201
|
}
|
|
195
202
|
|
|
196
|
-
def __init__(
|
|
203
|
+
def __init__(
|
|
204
|
+
self,
|
|
205
|
+
dbt_cloud_conn_id: str = default_conn_name,
|
|
206
|
+
timeout_seconds: int | None = None,
|
|
207
|
+
retry_limit: int = 1,
|
|
208
|
+
retry_delay: float = 1.0,
|
|
209
|
+
retry_args: dict[Any, Any] | None = None,
|
|
210
|
+
) -> None:
|
|
197
211
|
super().__init__(auth_type=TokenAuth)
|
|
198
212
|
self.dbt_cloud_conn_id = dbt_cloud_conn_id
|
|
213
|
+
self.timeout_seconds = timeout_seconds
|
|
214
|
+
if retry_limit < 1:
|
|
215
|
+
raise ValueError("Retry limit must be greater than or equal to 1")
|
|
216
|
+
self.retry_limit = retry_limit
|
|
217
|
+
self.retry_delay = retry_delay
|
|
218
|
+
|
|
219
|
+
def retry_after_func(retry_state: RetryCallState) -> None:
|
|
220
|
+
error_msg = str(retry_state.outcome.exception()) if retry_state.outcome else "Unknown error"
|
|
221
|
+
self._log_request_error(retry_state.attempt_number, error_msg)
|
|
222
|
+
|
|
223
|
+
if retry_args:
|
|
224
|
+
self.retry_args = copy.copy(retry_args)
|
|
225
|
+
self.retry_args["retry"] = retry_if_exception(self._retryable_error)
|
|
226
|
+
self.retry_args["after"] = retry_after_func
|
|
227
|
+
self.retry_args["reraise"] = True
|
|
228
|
+
else:
|
|
229
|
+
self.retry_args = {
|
|
230
|
+
"stop": stop_after_attempt(self.retry_limit),
|
|
231
|
+
"wait": wait_exponential(min=self.retry_delay, max=(2**retry_limit)),
|
|
232
|
+
"retry": retry_if_exception(self._retryable_error),
|
|
233
|
+
"after": retry_after_func,
|
|
234
|
+
"reraise": True,
|
|
235
|
+
}
|
|
199
236
|
|
|
200
237
|
@staticmethod
|
|
201
238
|
def _get_tenant_domain(conn: Connection) -> str:
|
|
@@ -233,6 +270,36 @@ class DbtCloudHook(HttpHook):
|
|
|
233
270
|
headers["Authorization"] = f"Token {self.connection.password}"
|
|
234
271
|
return headers, tenant
|
|
235
272
|
|
|
273
|
+
def _log_request_error(self, attempt_num: int, error: str) -> None:
|
|
274
|
+
self.log.error("Attempt %s API Request to DBT failed with reason: %s", attempt_num, error)
|
|
275
|
+
|
|
276
|
+
@staticmethod
|
|
277
|
+
def _retryable_error(exception: BaseException) -> bool:
|
|
278
|
+
if isinstance(exception, requests_exceptions.RequestException):
|
|
279
|
+
if isinstance(exception, (requests_exceptions.ConnectionError, requests_exceptions.Timeout)) or (
|
|
280
|
+
exception.response is not None
|
|
281
|
+
and (exception.response.status_code >= 500 or exception.response.status_code == 429)
|
|
282
|
+
):
|
|
283
|
+
return True
|
|
284
|
+
|
|
285
|
+
if isinstance(exception, aiohttp.ClientResponseError):
|
|
286
|
+
if exception.status >= 500 or exception.status == 429:
|
|
287
|
+
return True
|
|
288
|
+
|
|
289
|
+
if isinstance(exception, (aiohttp.ClientConnectorError, TimeoutError)):
|
|
290
|
+
return True
|
|
291
|
+
|
|
292
|
+
return False
|
|
293
|
+
|
|
294
|
+
def _a_get_retry_object(self) -> AsyncRetrying:
|
|
295
|
+
"""
|
|
296
|
+
Instantiate an async retry object.
|
|
297
|
+
|
|
298
|
+
:return: instance of AsyncRetrying class
|
|
299
|
+
"""
|
|
300
|
+
# for compatibility we use reraise to avoid handling request error
|
|
301
|
+
return AsyncRetrying(**self.retry_args)
|
|
302
|
+
|
|
236
303
|
@provide_account_id
|
|
237
304
|
async def get_job_details(
|
|
238
305
|
self, run_id: int, account_id: int | None = None, include_related: list[str] | None = None
|
|
@@ -249,17 +316,22 @@ class DbtCloudHook(HttpHook):
|
|
|
249
316
|
headers, tenant = await self.get_headers_tenants_from_connection()
|
|
250
317
|
url, params = self.get_request_url_params(tenant, endpoint, include_related)
|
|
251
318
|
proxies = self._get_proxies(self.connection) or {}
|
|
319
|
+
proxy = proxies.get("https") if proxies and url.startswith("https") else proxies.get("http")
|
|
320
|
+
extra_request_args = {}
|
|
252
321
|
|
|
253
|
-
|
|
254
|
-
proxy =
|
|
255
|
-
extra_request_args = {}
|
|
322
|
+
if proxy:
|
|
323
|
+
extra_request_args["proxy"] = proxy
|
|
256
324
|
|
|
257
|
-
|
|
258
|
-
|
|
325
|
+
timeout = (
|
|
326
|
+
aiohttp.ClientTimeout(total=self.timeout_seconds) if self.timeout_seconds is not None else None
|
|
327
|
+
)
|
|
259
328
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
329
|
+
async with aiohttp.ClientSession(headers=headers, timeout=timeout) as session:
|
|
330
|
+
async for attempt in self._a_get_retry_object():
|
|
331
|
+
with attempt:
|
|
332
|
+
async with session.get(url, params=params, **extra_request_args) as response: # type: ignore[arg-type]
|
|
333
|
+
response.raise_for_status()
|
|
334
|
+
return await response.json()
|
|
263
335
|
|
|
264
336
|
async def get_job_status(
|
|
265
337
|
self, run_id: int, account_id: int | None = None, include_related: list[str] | None = None
|
|
@@ -297,8 +369,14 @@ class DbtCloudHook(HttpHook):
|
|
|
297
369
|
def _paginate(
|
|
298
370
|
self, endpoint: str, payload: dict[str, Any] | None = None, proxies: dict[str, str] | None = None
|
|
299
371
|
) -> list[Response]:
|
|
300
|
-
extra_options = {
|
|
301
|
-
|
|
372
|
+
extra_options: dict[str, Any] = {}
|
|
373
|
+
if self.timeout_seconds is not None:
|
|
374
|
+
extra_options["timeout"] = self.timeout_seconds
|
|
375
|
+
if proxies is not None:
|
|
376
|
+
extra_options["proxies"] = proxies
|
|
377
|
+
response = self.run_with_advanced_retry(
|
|
378
|
+
_retry_args=self.retry_args, endpoint=endpoint, data=payload, extra_options=extra_options or None
|
|
379
|
+
)
|
|
302
380
|
resp_json = response.json()
|
|
303
381
|
limit = resp_json["extra"]["filters"]["limit"]
|
|
304
382
|
num_total_results = resp_json["extra"]["pagination"]["total_count"]
|
|
@@ -309,7 +387,12 @@ class DbtCloudHook(HttpHook):
|
|
|
309
387
|
_paginate_payload["offset"] = limit
|
|
310
388
|
|
|
311
389
|
while num_current_results < num_total_results:
|
|
312
|
-
response = self.
|
|
390
|
+
response = self.run_with_advanced_retry(
|
|
391
|
+
_retry_args=self.retry_args,
|
|
392
|
+
endpoint=endpoint,
|
|
393
|
+
data=_paginate_payload,
|
|
394
|
+
extra_options=extra_options,
|
|
395
|
+
)
|
|
313
396
|
resp_json = response.json()
|
|
314
397
|
results.append(response)
|
|
315
398
|
num_current_results += resp_json["extra"]["pagination"]["count"]
|
|
@@ -328,7 +411,11 @@ class DbtCloudHook(HttpHook):
|
|
|
328
411
|
self.method = method
|
|
329
412
|
full_endpoint = f"api/{api_version}/accounts/{endpoint}" if endpoint else None
|
|
330
413
|
proxies = self._get_proxies(self.connection)
|
|
331
|
-
extra_options = {
|
|
414
|
+
extra_options: dict[str, Any] = {}
|
|
415
|
+
if self.timeout_seconds is not None:
|
|
416
|
+
extra_options["timeout"] = self.timeout_seconds
|
|
417
|
+
if proxies is not None:
|
|
418
|
+
extra_options["proxies"] = proxies
|
|
332
419
|
|
|
333
420
|
if paginate:
|
|
334
421
|
if isinstance(payload, str):
|
|
@@ -339,7 +426,12 @@ class DbtCloudHook(HttpHook):
|
|
|
339
426
|
|
|
340
427
|
raise ValueError("An endpoint is needed to paginate a response.")
|
|
341
428
|
|
|
342
|
-
return self.
|
|
429
|
+
return self.run_with_advanced_retry(
|
|
430
|
+
_retry_args=self.retry_args,
|
|
431
|
+
endpoint=full_endpoint,
|
|
432
|
+
data=payload,
|
|
433
|
+
extra_options=extra_options or None,
|
|
434
|
+
)
|
|
343
435
|
|
|
344
436
|
def list_accounts(self) -> list[Response]:
|
|
345
437
|
"""
|
|
@@ -24,6 +24,7 @@ from pathlib import Path
|
|
|
24
24
|
from typing import TYPE_CHECKING, Any
|
|
25
25
|
|
|
26
26
|
from airflow.configuration import conf
|
|
27
|
+
from airflow.providers.common.compat.sdk import BaseOperator, BaseOperatorLink, XCom
|
|
27
28
|
from airflow.providers.dbt.cloud.hooks.dbt import (
|
|
28
29
|
DbtCloudHook,
|
|
29
30
|
DbtCloudJobRunException,
|
|
@@ -32,11 +33,6 @@ from airflow.providers.dbt.cloud.hooks.dbt import (
|
|
|
32
33
|
)
|
|
33
34
|
from airflow.providers.dbt.cloud.triggers.dbt import DbtCloudRunJobTrigger
|
|
34
35
|
from airflow.providers.dbt.cloud.utils.openlineage import generate_openlineage_events_from_dbt_cloud_run
|
|
35
|
-
from airflow.providers.dbt.cloud.version_compat import (
|
|
36
|
-
BaseOperator,
|
|
37
|
-
BaseOperatorLink,
|
|
38
|
-
XCom,
|
|
39
|
-
)
|
|
40
36
|
|
|
41
37
|
if TYPE_CHECKING:
|
|
42
38
|
from airflow.providers.openlineage.extractors import OperatorLineage
|
|
@@ -87,6 +83,7 @@ class DbtCloudRunJobOperator(BaseOperator):
|
|
|
87
83
|
run. For more information on retry logic, see:
|
|
88
84
|
https://docs.getdbt.com/dbt-cloud/api-v2#/operations/Retry%20Failed%20Job
|
|
89
85
|
:param deferrable: Run operator in the deferrable mode
|
|
86
|
+
:param hook_params: Extra arguments passed to the DbtCloudHook constructor.
|
|
90
87
|
:return: The ID of the triggered dbt Cloud job run.
|
|
91
88
|
"""
|
|
92
89
|
|
|
@@ -124,6 +121,7 @@ class DbtCloudRunJobOperator(BaseOperator):
|
|
|
124
121
|
reuse_existing_run: bool = False,
|
|
125
122
|
retry_from_failure: bool = False,
|
|
126
123
|
deferrable: bool = conf.getboolean("operators", "default_deferrable", fallback=False),
|
|
124
|
+
hook_params: dict[str, Any] | None = None,
|
|
127
125
|
**kwargs,
|
|
128
126
|
) -> None:
|
|
129
127
|
super().__init__(**kwargs)
|
|
@@ -144,6 +142,7 @@ class DbtCloudRunJobOperator(BaseOperator):
|
|
|
144
142
|
self.reuse_existing_run = reuse_existing_run
|
|
145
143
|
self.retry_from_failure = retry_from_failure
|
|
146
144
|
self.deferrable = deferrable
|
|
145
|
+
self.hook_params = hook_params or {}
|
|
147
146
|
|
|
148
147
|
def execute(self, context: Context):
|
|
149
148
|
if self.trigger_reason is None:
|
|
@@ -273,7 +272,7 @@ class DbtCloudRunJobOperator(BaseOperator):
|
|
|
273
272
|
@cached_property
|
|
274
273
|
def hook(self):
|
|
275
274
|
"""Returns DBT Cloud hook."""
|
|
276
|
-
return DbtCloudHook(self.dbt_cloud_conn_id)
|
|
275
|
+
return DbtCloudHook(self.dbt_cloud_conn_id, **self.hook_params)
|
|
277
276
|
|
|
278
277
|
def get_openlineage_facets_on_complete(self, task_instance) -> OperatorLineage:
|
|
279
278
|
"""
|
|
@@ -311,6 +310,7 @@ class DbtCloudGetJobRunArtifactOperator(BaseOperator):
|
|
|
311
310
|
be returned.
|
|
312
311
|
:param output_file_name: Optional. The desired file name for the download artifact file.
|
|
313
312
|
Defaults to <run_id>_<path> (e.g. "728368_run_results.json").
|
|
313
|
+
:param hook_params: Extra arguments passed to the DbtCloudHook constructor.
|
|
314
314
|
"""
|
|
315
315
|
|
|
316
316
|
template_fields = ("dbt_cloud_conn_id", "run_id", "path", "account_id", "output_file_name")
|
|
@@ -324,6 +324,7 @@ class DbtCloudGetJobRunArtifactOperator(BaseOperator):
|
|
|
324
324
|
account_id: int | None = None,
|
|
325
325
|
step: int | None = None,
|
|
326
326
|
output_file_name: str | None = None,
|
|
327
|
+
hook_params: dict[str, Any] | None = None,
|
|
327
328
|
**kwargs,
|
|
328
329
|
) -> None:
|
|
329
330
|
super().__init__(**kwargs)
|
|
@@ -333,9 +334,10 @@ class DbtCloudGetJobRunArtifactOperator(BaseOperator):
|
|
|
333
334
|
self.account_id = account_id
|
|
334
335
|
self.step = step
|
|
335
336
|
self.output_file_name = output_file_name or f"{self.run_id}_{self.path}".replace("/", "-")
|
|
337
|
+
self.hook_params = hook_params or {}
|
|
336
338
|
|
|
337
339
|
def execute(self, context: Context) -> str:
|
|
338
|
-
hook = DbtCloudHook(self.dbt_cloud_conn_id)
|
|
340
|
+
hook = DbtCloudHook(self.dbt_cloud_conn_id, **self.hook_params)
|
|
339
341
|
response = hook.get_job_run_artifact(
|
|
340
342
|
run_id=self.run_id, path=self.path, account_id=self.account_id, step=self.step
|
|
341
343
|
)
|
|
@@ -370,6 +372,7 @@ class DbtCloudListJobsOperator(BaseOperator):
|
|
|
370
372
|
:param order_by: Optional. Field to order the result by. Use '-' to indicate reverse order.
|
|
371
373
|
For example, to use reverse order by the run ID use ``order_by=-id``.
|
|
372
374
|
:param project_id: Optional. The ID of a dbt Cloud project.
|
|
375
|
+
:param hook_params: Extra arguments passed to the DbtCloudHook constructor.
|
|
373
376
|
"""
|
|
374
377
|
|
|
375
378
|
template_fields = (
|
|
@@ -384,6 +387,7 @@ class DbtCloudListJobsOperator(BaseOperator):
|
|
|
384
387
|
account_id: int | None = None,
|
|
385
388
|
project_id: int | None = None,
|
|
386
389
|
order_by: str | None = None,
|
|
390
|
+
hook_params: dict[str, Any] | None = None,
|
|
387
391
|
**kwargs,
|
|
388
392
|
) -> None:
|
|
389
393
|
super().__init__(**kwargs)
|
|
@@ -391,9 +395,10 @@ class DbtCloudListJobsOperator(BaseOperator):
|
|
|
391
395
|
self.account_id = account_id
|
|
392
396
|
self.project_id = project_id
|
|
393
397
|
self.order_by = order_by
|
|
398
|
+
self.hook_params = hook_params or {}
|
|
394
399
|
|
|
395
400
|
def execute(self, context: Context) -> list:
|
|
396
|
-
hook = DbtCloudHook(self.dbt_cloud_conn_id)
|
|
401
|
+
hook = DbtCloudHook(self.dbt_cloud_conn_id, **self.hook_params)
|
|
397
402
|
list_jobs_response = hook.list_jobs(
|
|
398
403
|
account_id=self.account_id, order_by=self.order_by, project_id=self.project_id
|
|
399
404
|
)
|
|
@@ -22,15 +22,10 @@ from typing import TYPE_CHECKING, Any
|
|
|
22
22
|
|
|
23
23
|
from airflow.configuration import conf
|
|
24
24
|
from airflow.exceptions import AirflowException
|
|
25
|
+
from airflow.providers.common.compat.sdk import BaseSensorOperator
|
|
25
26
|
from airflow.providers.dbt.cloud.hooks.dbt import DbtCloudHook, DbtCloudJobRunException, DbtCloudJobRunStatus
|
|
26
27
|
from airflow.providers.dbt.cloud.triggers.dbt import DbtCloudRunJobTrigger
|
|
27
28
|
from airflow.providers.dbt.cloud.utils.openlineage import generate_openlineage_events_from_dbt_cloud_run
|
|
28
|
-
from airflow.providers.dbt.cloud.version_compat import AIRFLOW_V_3_0_PLUS
|
|
29
|
-
|
|
30
|
-
if AIRFLOW_V_3_0_PLUS:
|
|
31
|
-
from airflow.sdk import BaseSensorOperator
|
|
32
|
-
else:
|
|
33
|
-
from airflow.sensors.base import BaseSensorOperator # type: ignore[no-redef]
|
|
34
29
|
|
|
35
30
|
if TYPE_CHECKING:
|
|
36
31
|
from airflow.providers.openlineage.extractors import OperatorLineage
|
|
@@ -36,6 +36,7 @@ class DbtCloudRunJobTrigger(BaseTrigger):
|
|
|
36
36
|
:param end_time: Time in seconds to wait for a job run to reach a terminal status. Defaults to 7 days.
|
|
37
37
|
:param account_id: The ID of a dbt Cloud account.
|
|
38
38
|
:param poll_interval: polling period in seconds to check for the status.
|
|
39
|
+
:param hook_params: Extra arguments passed to the DbtCloudHook constructor.
|
|
39
40
|
"""
|
|
40
41
|
|
|
41
42
|
def __init__(
|
|
@@ -45,6 +46,7 @@ class DbtCloudRunJobTrigger(BaseTrigger):
|
|
|
45
46
|
end_time: float,
|
|
46
47
|
poll_interval: float,
|
|
47
48
|
account_id: int | None,
|
|
49
|
+
hook_params: dict[str, Any] | None = None,
|
|
48
50
|
):
|
|
49
51
|
super().__init__()
|
|
50
52
|
self.run_id = run_id
|
|
@@ -52,6 +54,7 @@ class DbtCloudRunJobTrigger(BaseTrigger):
|
|
|
52
54
|
self.conn_id = conn_id
|
|
53
55
|
self.end_time = end_time
|
|
54
56
|
self.poll_interval = poll_interval
|
|
57
|
+
self.hook_params = hook_params or {}
|
|
55
58
|
|
|
56
59
|
def serialize(self) -> tuple[str, dict[str, Any]]:
|
|
57
60
|
"""Serialize DbtCloudRunJobTrigger arguments and classpath."""
|
|
@@ -63,12 +66,13 @@ class DbtCloudRunJobTrigger(BaseTrigger):
|
|
|
63
66
|
"conn_id": self.conn_id,
|
|
64
67
|
"end_time": self.end_time,
|
|
65
68
|
"poll_interval": self.poll_interval,
|
|
69
|
+
"hook_params": self.hook_params,
|
|
66
70
|
},
|
|
67
71
|
)
|
|
68
72
|
|
|
69
73
|
async def run(self) -> AsyncIterator[TriggerEvent]:
|
|
70
74
|
"""Make async connection to Dbt, polls for the pipeline run status."""
|
|
71
|
-
hook = DbtCloudHook(self.conn_id)
|
|
75
|
+
hook = DbtCloudHook(self.conn_id, **self.hook_params)
|
|
72
76
|
try:
|
|
73
77
|
while await self.is_still_running(hook):
|
|
74
78
|
if self.end_time < time.time():
|
|
@@ -34,18 +34,6 @@ def get_base_airflow_version_tuple() -> tuple[int, int, int]:
|
|
|
34
34
|
|
|
35
35
|
AIRFLOW_V_3_0_PLUS = get_base_airflow_version_tuple() >= (3, 0, 0)
|
|
36
36
|
|
|
37
|
-
if AIRFLOW_V_3_0_PLUS:
|
|
38
|
-
from airflow.sdk import BaseOperator, BaseOperatorLink, BaseSensorOperator
|
|
39
|
-
from airflow.sdk.execution_time.xcom import XCom
|
|
40
|
-
else:
|
|
41
|
-
from airflow.models import BaseOperator, XCom
|
|
42
|
-
from airflow.models.baseoperatorlink import BaseOperatorLink # type: ignore[no-redef]
|
|
43
|
-
from airflow.sensors.base import BaseSensorOperator # type: ignore[no-redef]
|
|
44
|
-
|
|
45
37
|
__all__ = [
|
|
46
38
|
"AIRFLOW_V_3_0_PLUS",
|
|
47
|
-
"BaseOperator",
|
|
48
|
-
"BaseSensorOperator",
|
|
49
|
-
"BaseOperatorLink",
|
|
50
|
-
"XCom",
|
|
51
39
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apache-airflow-providers-dbt-cloud
|
|
3
|
-
Version: 4.4.
|
|
3
|
+
Version: 4.4.4
|
|
4
4
|
Summary: Provider package apache-airflow-providers-dbt-cloud for Apache Airflow
|
|
5
5
|
Keywords: airflow-provider,dbt.cloud,airflow,integration
|
|
6
6
|
Author-email: Apache Software Foundation <dev@airflow.apache.org>
|
|
@@ -20,15 +20,16 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Classifier: Topic :: System :: Monitoring
|
|
23
|
-
Requires-Dist: apache-airflow>=2.10.
|
|
24
|
-
Requires-Dist: apache-airflow-providers-common-compat>=1.
|
|
23
|
+
Requires-Dist: apache-airflow>=2.10.0
|
|
24
|
+
Requires-Dist: apache-airflow-providers-common-compat>=1.8.0
|
|
25
25
|
Requires-Dist: apache-airflow-providers-http
|
|
26
26
|
Requires-Dist: asgiref>=2.3.0
|
|
27
27
|
Requires-Dist: aiohttp>=3.9.2
|
|
28
|
-
Requires-Dist:
|
|
28
|
+
Requires-Dist: tenacity>=8.3.0
|
|
29
|
+
Requires-Dist: apache-airflow-providers-openlineage>=2.3.0 ; extra == "openlineage"
|
|
29
30
|
Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
|
|
30
|
-
Project-URL: Changelog, https://airflow.
|
|
31
|
-
Project-URL: Documentation, https://airflow.
|
|
31
|
+
Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-dbt-cloud/4.4.4/changelog.html
|
|
32
|
+
Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-dbt-cloud/4.4.4
|
|
32
33
|
Project-URL: Mastodon, https://fosstodon.org/@airflow
|
|
33
34
|
Project-URL: Slack Chat, https://s.apache.org/airflow-slack
|
|
34
35
|
Project-URL: Source Code, https://github.com/apache/airflow
|
|
@@ -60,7 +61,7 @@ Provides-Extra: openlineage
|
|
|
60
61
|
|
|
61
62
|
Package ``apache-airflow-providers-dbt-cloud``
|
|
62
63
|
|
|
63
|
-
Release: ``4.4.
|
|
64
|
+
Release: ``4.4.4``
|
|
64
65
|
|
|
65
66
|
|
|
66
67
|
`dbt Cloud <https://www.getdbt.com/product/dbt-cloud/>`__
|
|
@@ -73,7 +74,7 @@ This is a provider package for ``dbt.cloud`` provider. All classes for this prov
|
|
|
73
74
|
are in ``airflow.providers.dbt.cloud`` python package.
|
|
74
75
|
|
|
75
76
|
You can find package information and changelog for the provider
|
|
76
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-dbt-cloud/4.4.
|
|
77
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-dbt-cloud/4.4.4/>`_.
|
|
77
78
|
|
|
78
79
|
Installation
|
|
79
80
|
------------
|
|
@@ -91,10 +92,11 @@ Requirements
|
|
|
91
92
|
PIP package Version required
|
|
92
93
|
========================================== ==================
|
|
93
94
|
``apache-airflow`` ``>=2.10.0``
|
|
94
|
-
``apache-airflow-providers-common-compat`` ``>=1.
|
|
95
|
+
``apache-airflow-providers-common-compat`` ``>=1.8.0``
|
|
95
96
|
``apache-airflow-providers-http``
|
|
96
97
|
``asgiref`` ``>=2.3.0``
|
|
97
98
|
``aiohttp`` ``>=3.9.2``
|
|
99
|
+
``tenacity`` ``>=8.3.0``
|
|
98
100
|
========================================== ==================
|
|
99
101
|
|
|
100
102
|
Cross provider package dependencies
|
|
@@ -118,6 +120,15 @@ Dependent package
|
|
|
118
120
|
`apache-airflow-providers-openlineage <https://airflow.apache.org/docs/apache-airflow-providers-openlineage>`_ ``openlineage``
|
|
119
121
|
================================================================================================================== =================
|
|
120
122
|
|
|
123
|
+
Optional dependencies
|
|
124
|
+
----------------------
|
|
125
|
+
|
|
126
|
+
=============== ===============================================
|
|
127
|
+
Extra Dependencies
|
|
128
|
+
=============== ===============================================
|
|
129
|
+
``openlineage`` ``apache-airflow-providers-openlineage>=2.3.0``
|
|
130
|
+
=============== ===============================================
|
|
131
|
+
|
|
121
132
|
The changelog for the provider package can be found in the
|
|
122
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-dbt-cloud/4.4.
|
|
133
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-dbt-cloud/4.4.4/changelog.html>`_.
|
|
123
134
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
airflow/providers/dbt/cloud/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
|
|
2
|
+
airflow/providers/dbt/cloud/__init__.py,sha256=W4cZ3hUYJLy1BNH2L-IsRndS3FN2pW2xA5z-n-BRQmY,1498
|
|
3
|
+
airflow/providers/dbt/cloud/get_provider_info.py,sha256=ufODYanp90_NPW1UftzGIwwG65Olb5l5PfSp0Mo1SOs,2507
|
|
4
|
+
airflow/providers/dbt/cloud/version_compat.py,sha256=RQbdCueLOaFZWekpQmF0BoAoJInW8EoyvJ3Ah-HbrPo,1577
|
|
5
|
+
airflow/providers/dbt/cloud/hooks/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
6
|
+
airflow/providers/dbt/cloud/hooks/dbt.py,sha256=uIzeZ5RlpubgNWNiQCcb57R2uTeTqW3R4rlD3ftFdSQ,38454
|
|
7
|
+
airflow/providers/dbt/cloud/operators/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
8
|
+
airflow/providers/dbt/cloud/operators/dbt.py,sha256=YAdnm_FT6cq9iprIrSmpAzgd_O240VJqNs51zExSak4,18389
|
|
9
|
+
airflow/providers/dbt/cloud/sensors/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
|
|
10
|
+
airflow/providers/dbt/cloud/sensors/dbt.py,sha256=NigUphQQPjIy4ySsrFL8xJHVfgoOWKoyhRFMspuf6_4,5172
|
|
11
|
+
airflow/providers/dbt/cloud/triggers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
12
|
+
airflow/providers/dbt/cloud/triggers/dbt.py,sha256=p6-LU2GPpEZ2DtL4ZTkG7OIVAFCblKYbjV9z49ooltI,4952
|
|
13
|
+
airflow/providers/dbt/cloud/utils/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
14
|
+
airflow/providers/dbt/cloud/utils/openlineage.py,sha256=uUgIF6GyVMLY2G1g6TP3ai2C22avap5nESDJ5TeJMFw,8042
|
|
15
|
+
apache_airflow_providers_dbt_cloud-4.4.4.dist-info/entry_points.txt,sha256=c18L1WEEK18WQeEGrm9kMVqutiYJHiWGH5jU1JqnToE,105
|
|
16
|
+
apache_airflow_providers_dbt_cloud-4.4.4.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
17
|
+
apache_airflow_providers_dbt_cloud-4.4.4.dist-info/METADATA,sha256=yUP99VIof_9y-epTSiBDTAjYEuQE-zOalstBcM6jhEs,6185
|
|
18
|
+
apache_airflow_providers_dbt_cloud-4.4.4.dist-info/RECORD,,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
airflow/providers/dbt/cloud/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
|
|
2
|
-
airflow/providers/dbt/cloud/__init__.py,sha256=QTyj3OpJEad4cqlnDCPU-PzBzCtmI_ufKAYv3JNk7Zk,1498
|
|
3
|
-
airflow/providers/dbt/cloud/get_provider_info.py,sha256=ufODYanp90_NPW1UftzGIwwG65Olb5l5PfSp0Mo1SOs,2507
|
|
4
|
-
airflow/providers/dbt/cloud/version_compat.py,sha256=xlj-5p7JK_pkXUjSEuNRRq9GxBOmhA0AayCPlMh_XiM,2044
|
|
5
|
-
airflow/providers/dbt/cloud/hooks/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
6
|
-
airflow/providers/dbt/cloud/hooks/dbt.py,sha256=ltmfXlILc3GNuckl54AyGDCREkfnP_4qNR983ylw9fI,34568
|
|
7
|
-
airflow/providers/dbt/cloud/operators/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
8
|
-
airflow/providers/dbt/cloud/operators/dbt.py,sha256=WjarCOzQHAxZXY-zloAFU95KTLtQUEman1SRpDK55YE,17825
|
|
9
|
-
airflow/providers/dbt/cloud/sensors/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
|
|
10
|
-
airflow/providers/dbt/cloud/sensors/dbt.py,sha256=x3F077-nTjxOEfQlgDuICIRJTQMnmc59yfesLZ3AOmE,5338
|
|
11
|
-
airflow/providers/dbt/cloud/triggers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
12
|
-
airflow/providers/dbt/cloud/triggers/dbt.py,sha256=Oabdc7FcNhCQxkjDC5SqAiYEw4hSZ9mQGZgSt36a1E0,4707
|
|
13
|
-
airflow/providers/dbt/cloud/utils/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
14
|
-
airflow/providers/dbt/cloud/utils/openlineage.py,sha256=uUgIF6GyVMLY2G1g6TP3ai2C22avap5nESDJ5TeJMFw,8042
|
|
15
|
-
apache_airflow_providers_dbt_cloud-4.4.3rc1.dist-info/entry_points.txt,sha256=c18L1WEEK18WQeEGrm9kMVqutiYJHiWGH5jU1JqnToE,105
|
|
16
|
-
apache_airflow_providers_dbt_cloud-4.4.3rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
17
|
-
apache_airflow_providers_dbt_cloud-4.4.3rc1.dist-info/METADATA,sha256=UrC1n8EIVeSm8-y4Qn-s0MvdS1iSqrIc6Bnfsvu1Owg,5787
|
|
18
|
-
apache_airflow_providers_dbt_cloud-4.4.3rc1.dist-info/RECORD,,
|
|
File without changes
|