apache-airflow-providers-dbt-cloud 4.4.3rc1__py3-none-any.whl → 4.6.0rc1__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.
@@ -29,11 +29,11 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "4.4.3"
32
+ __version__ = "4.6.0"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
- "2.10.0"
35
+ "2.11.0"
36
36
  ):
37
37
  raise RuntimeError(
38
- f"The package `apache-airflow-providers-dbt-cloud:{__version__}` needs Apache Airflow 2.10.0+"
38
+ f"The package `apache-airflow-providers-dbt-cloud:{__version__}` needs Apache Airflow 2.11.0+"
39
39
  )
@@ -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__(self, dbt_cloud_conn_id: str = default_conn_name, *args, **kwargs) -> None:
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
- async with aiohttp.ClientSession(headers=headers) as session:
254
- proxy = proxies.get("https") if proxies and url.startswith("https") else proxies.get("http")
255
- extra_request_args = {}
322
+ if proxy:
323
+ extra_request_args["proxy"] = proxy
256
324
 
257
- if proxy:
258
- extra_request_args["proxy"] = proxy
325
+ timeout = (
326
+ aiohttp.ClientTimeout(total=self.timeout_seconds) if self.timeout_seconds is not None else None
327
+ )
259
328
 
260
- async with session.get(url, params=params, **extra_request_args) as response: # type: ignore[arg-type]
261
- response.raise_for_status()
262
- return await response.json()
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 = {"proxies": proxies} if proxies is not None else None
301
- response = self.run(endpoint=endpoint, data=payload, extra_options=extra_options)
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.run(endpoint=endpoint, data=_paginate_payload, extra_options=extra_options)
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 = {"proxies": proxies} if proxies is not None else None
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.run(endpoint=full_endpoint, data=payload, extra_options=extra_options)
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
@@ -60,6 +55,7 @@ class DbtCloudJobRunSensor(BaseSensorOperator):
60
55
  run_id: int,
61
56
  account_id: int | None = None,
62
57
  deferrable: bool = conf.getboolean("operators", "default_deferrable", fallback=False),
58
+ hook_params: dict[str, Any] | None = None,
63
59
  **kwargs,
64
60
  ) -> None:
65
61
  if deferrable:
@@ -73,13 +69,13 @@ class DbtCloudJobRunSensor(BaseSensorOperator):
73
69
  self.dbt_cloud_conn_id = dbt_cloud_conn_id
74
70
  self.run_id = run_id
75
71
  self.account_id = account_id
76
-
72
+ self.hook_params = hook_params or {}
77
73
  self.deferrable = deferrable
78
74
 
79
75
  @cached_property
80
76
  def hook(self):
81
77
  """Returns DBT Cloud hook."""
82
- return DbtCloudHook(self.dbt_cloud_conn_id)
78
+ return DbtCloudHook(self.dbt_cloud_conn_id, **self.hook_params)
83
79
 
84
80
  def poke(self, context: Context) -> bool:
85
81
  job_run_status = self.hook.get_job_run_status(run_id=self.run_id, account_id=self.account_id)
@@ -115,6 +111,7 @@ class DbtCloudJobRunSensor(BaseSensorOperator):
115
111
  account_id=self.account_id,
116
112
  poll_interval=self.poke_interval,
117
113
  end_time=end_time,
114
+ hook_params=self.hook_params,
118
115
  ),
119
116
  method_name="execute_complete",
120
117
  )
@@ -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,12 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apache-airflow-providers-dbt-cloud
3
- Version: 4.4.3rc1
3
+ Version: 4.6.0rc1
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>
7
7
  Maintainer-email: Apache Software Foundation <dev@airflow.apache.org>
8
8
  Requires-Python: >=3.10
9
9
  Description-Content-Type: text/x-rst
10
+ License-Expression: Apache-2.0
10
11
  Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: Environment :: Console
12
13
  Classifier: Environment :: Web Environment
@@ -14,21 +15,23 @@ Classifier: Intended Audience :: Developers
14
15
  Classifier: Intended Audience :: System Administrators
15
16
  Classifier: Framework :: Apache Airflow
16
17
  Classifier: Framework :: Apache Airflow :: Provider
17
- Classifier: License :: OSI Approved :: Apache Software License
18
18
  Classifier: Programming Language :: Python :: 3.10
19
19
  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.0rc1
24
- Requires-Dist: apache-airflow-providers-common-compat>=1.6.0rc1
23
+ License-File: LICENSE
24
+ License-File: NOTICE
25
+ Requires-Dist: apache-airflow>=2.11.0rc1
26
+ Requires-Dist: apache-airflow-providers-common-compat>=1.8.0rc1
25
27
  Requires-Dist: apache-airflow-providers-http
26
28
  Requires-Dist: asgiref>=2.3.0
27
29
  Requires-Dist: aiohttp>=3.9.2
30
+ Requires-Dist: tenacity>=8.3.0
28
31
  Requires-Dist: apache-airflow-providers-openlineage>=2.3.0rc1 ; extra == "openlineage"
29
32
  Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
30
- Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-dbt-cloud/4.4.3/changelog.html
31
- Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-dbt-cloud/4.4.3
33
+ Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-dbt-cloud/4.6.0/changelog.html
34
+ Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-dbt-cloud/4.6.0
32
35
  Project-URL: Mastodon, https://fosstodon.org/@airflow
33
36
  Project-URL: Slack Chat, https://s.apache.org/airflow-slack
34
37
  Project-URL: Source Code, https://github.com/apache/airflow
@@ -60,7 +63,7 @@ Provides-Extra: openlineage
60
63
 
61
64
  Package ``apache-airflow-providers-dbt-cloud``
62
65
 
63
- Release: ``4.4.3``
66
+ Release: ``4.6.0``
64
67
 
65
68
 
66
69
  `dbt Cloud <https://www.getdbt.com/product/dbt-cloud/>`__
@@ -73,7 +76,7 @@ This is a provider package for ``dbt.cloud`` provider. All classes for this prov
73
76
  are in ``airflow.providers.dbt.cloud`` python package.
74
77
 
75
78
  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.3/>`_.
79
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-dbt-cloud/4.6.0/>`_.
77
80
 
78
81
  Installation
79
82
  ------------
@@ -90,11 +93,12 @@ Requirements
90
93
  ========================================== ==================
91
94
  PIP package Version required
92
95
  ========================================== ==================
93
- ``apache-airflow`` ``>=2.10.0``
94
- ``apache-airflow-providers-common-compat`` ``>=1.6.0``
96
+ ``apache-airflow`` ``>=2.11.0``
97
+ ``apache-airflow-providers-common-compat`` ``>=1.8.0``
95
98
  ``apache-airflow-providers-http``
96
99
  ``asgiref`` ``>=2.3.0``
97
100
  ``aiohttp`` ``>=3.9.2``
101
+ ``tenacity`` ``>=8.3.0``
98
102
  ========================================== ==================
99
103
 
100
104
  Cross provider package dependencies
@@ -118,6 +122,15 @@ Dependent package
118
122
  `apache-airflow-providers-openlineage <https://airflow.apache.org/docs/apache-airflow-providers-openlineage>`_ ``openlineage``
119
123
  ================================================================================================================== =================
120
124
 
125
+ Optional dependencies
126
+ ----------------------
127
+
128
+ =============== ===============================================
129
+ Extra Dependencies
130
+ =============== ===============================================
131
+ ``openlineage`` ``apache-airflow-providers-openlineage>=2.3.0``
132
+ =============== ===============================================
133
+
121
134
  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.3/changelog.html>`_.
135
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-dbt-cloud/4.6.0/changelog.html>`_.
123
136
 
@@ -0,0 +1,19 @@
1
+ airflow/providers/dbt/cloud/__init__.py,sha256=CtqFFf-5EoPitgyXqi0tvZiofVSCeZ1qIdp-JYuC_3I,1498
2
+ airflow/providers/dbt/cloud/get_provider_info.py,sha256=ufODYanp90_NPW1UftzGIwwG65Olb5l5PfSp0Mo1SOs,2507
3
+ airflow/providers/dbt/cloud/version_compat.py,sha256=RQbdCueLOaFZWekpQmF0BoAoJInW8EoyvJ3Ah-HbrPo,1577
4
+ airflow/providers/dbt/cloud/hooks/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
5
+ airflow/providers/dbt/cloud/hooks/dbt.py,sha256=uIzeZ5RlpubgNWNiQCcb57R2uTeTqW3R4rlD3ftFdSQ,38454
6
+ airflow/providers/dbt/cloud/operators/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
7
+ airflow/providers/dbt/cloud/operators/dbt.py,sha256=YAdnm_FT6cq9iprIrSmpAzgd_O240VJqNs51zExSak4,18389
8
+ airflow/providers/dbt/cloud/sensors/__init__.py,sha256=mlJxuZLkd5x-iq2SBwD3mvRQpt3YR7wjz_nceyF1IaI,787
9
+ airflow/providers/dbt/cloud/sensors/dbt.py,sha256=jHkZKNmMF97pYmSMeBq0XWN8g43ctnUOLvHPqrqUn8c,5341
10
+ airflow/providers/dbt/cloud/triggers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
11
+ airflow/providers/dbt/cloud/triggers/dbt.py,sha256=p6-LU2GPpEZ2DtL4ZTkG7OIVAFCblKYbjV9z49ooltI,4952
12
+ airflow/providers/dbt/cloud/utils/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
13
+ airflow/providers/dbt/cloud/utils/openlineage.py,sha256=uUgIF6GyVMLY2G1g6TP3ai2C22avap5nESDJ5TeJMFw,8042
14
+ apache_airflow_providers_dbt_cloud-4.6.0rc1.dist-info/entry_points.txt,sha256=c18L1WEEK18WQeEGrm9kMVqutiYJHiWGH5jU1JqnToE,105
15
+ apache_airflow_providers_dbt_cloud-4.6.0rc1.dist-info/licenses/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
16
+ apache_airflow_providers_dbt_cloud-4.6.0rc1.dist-info/licenses/NOTICE,sha256=E3-_E02gwwSEFzeeWPKmnIjOoos3hW28CLISV6sYrbQ,168
17
+ apache_airflow_providers_dbt_cloud-4.6.0rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
18
+ apache_airflow_providers_dbt_cloud-4.6.0rc1.dist-info/METADATA,sha256=xxOa_AaLyVztuEq64laSgliODa-2CEYikcBbBNRIZss,6222
19
+ apache_airflow_providers_dbt_cloud-4.6.0rc1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Apache Airflow
2
+ Copyright 2016-2025 The Apache Software Foundation
3
+
4
+ This product includes software developed at
5
+ The Apache Software Foundation (http://www.apache.org/).
@@ -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,,