airflow-dbt-python 3.0.1__tar.gz → 3.0.3__tar.gz

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 (29) hide show
  1. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/PKG-INFO +38 -37
  2. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/README.md +7 -7
  3. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/__version__.py +1 -1
  4. airflow_dbt_python-3.0.3/airflow_dbt_python/hooks/__init__.py +1 -0
  5. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/hooks/dbt.py +5 -1
  6. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/hooks/fs/__init__.py +3 -4
  7. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/hooks/target.py +32 -2
  8. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/operators/dbt.py +17 -9
  9. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/utils/configs.py +9 -3
  10. airflow_dbt_python-3.0.3/airflow_dbt_python.egg-info/PKG-INFO +285 -0
  11. airflow_dbt_python-3.0.3/airflow_dbt_python.egg-info/SOURCES.txt +26 -0
  12. airflow_dbt_python-3.0.3/airflow_dbt_python.egg-info/dependency_links.txt +1 -0
  13. airflow_dbt_python-3.0.3/airflow_dbt_python.egg-info/requires.txt +42 -0
  14. airflow_dbt_python-3.0.3/airflow_dbt_python.egg-info/top_level.txt +1 -0
  15. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/pyproject.toml +32 -64
  16. airflow_dbt_python-3.0.3/setup.cfg +4 -0
  17. airflow_dbt_python-3.0.1/airflow_dbt_python/hooks/__init__.py +0 -1
  18. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/LICENSE +0 -0
  19. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/__init__.py +0 -0
  20. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/hooks/fs/gcs.py +0 -0
  21. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/hooks/fs/git.py +0 -0
  22. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/hooks/fs/local.py +0 -0
  23. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/hooks/fs/s3.py +0 -0
  24. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/operators/__init__.py +0 -0
  25. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/utils/__init__.py +0 -0
  26. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/utils/enums.py +0 -0
  27. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/utils/env.py +0 -0
  28. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/utils/url.py +0 -0
  29. {airflow_dbt_python-3.0.1 → airflow_dbt_python-3.0.3}/airflow_dbt_python/utils/version.py +0 -0
@@ -1,49 +1,51 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: airflow-dbt-python
3
- Version: 3.0.1
3
+ Version: 3.0.3
4
4
  Summary: A collection of Airflow operators, hooks, and utilities to execute dbt commands
5
- License: MIT
6
- Author: Tomás Farías Santana
7
- Author-email: tomas@tomasfarias.dev
8
- Requires-Python: >=3.9,<3.13
5
+ Author-email: Tomás Farías Santana <tomas@tomasfarias.dev>
6
+ License-Expression: MIT
7
+ Project-URL: repository, https://github.com/tomasfarias/airflow-dbt-python
8
+ Project-URL: documentation, https://airflow-dbt-python.readthedocs.io
9
9
  Classifier: Development Status :: 5 - Production/Stable
10
10
  Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: MIT License
12
11
  Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
15
14
  Classifier: Programming Language :: Python :: 3.12
16
- Provides-Extra: adapters
15
+ Requires-Python: <3.13,>=3.9
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: apache-airflow>=2.8
19
+ Requires-Dist: contextlib-chdir==1.0.2; python_version < "3.11"
20
+ Requires-Dist: dbt-core<2.0.0,>=1.8.0
17
21
  Provides-Extra: airflow-providers
22
+ Requires-Dist: apache-airflow-providers-amazon>=3.0.0; extra == "airflow-providers"
23
+ Requires-Dist: apache-airflow-providers-google>=11.0.0; extra == "airflow-providers"
24
+ Requires-Dist: apache-airflow-providers-ssh>=3.0.0; extra == "airflow-providers"
25
+ Provides-Extra: adapters
26
+ Requires-Dist: dbt-bigquery<2.0.0,>=1.8.0; extra == "adapters"
27
+ Requires-Dist: dbt-redshift<2.0.0,>=1.8.0; extra == "adapters"
28
+ Requires-Dist: dbt-postgres<2.0.0,>=1.8.0; extra == "adapters"
29
+ Requires-Dist: dbt-snowflake<2.0.0,>=1.8.0; extra == "adapters"
30
+ Requires-Dist: dbt-spark[all]<2.0.0,>=1.8.0; extra == "adapters"
18
31
  Provides-Extra: bigquery
32
+ Requires-Dist: dbt-bigquery<2.0.0,>=1.8.0; extra == "bigquery"
19
33
  Provides-Extra: gcs
34
+ Requires-Dist: apache-airflow-providers-google>=11.0.0; extra == "gcs"
20
35
  Provides-Extra: git
36
+ Requires-Dist: apache-airflow-providers-ssh>=3.0.0; extra == "git"
37
+ Requires-Dist: dulwich>=0.21; extra == "git"
21
38
  Provides-Extra: postgres
39
+ Requires-Dist: dbt-postgres<2.0.0,>=1.8.0; extra == "postgres"
22
40
  Provides-Extra: redshift
41
+ Requires-Dist: dbt-redshift<2.0.0,>=1.8.0; extra == "redshift"
23
42
  Provides-Extra: s3
43
+ Requires-Dist: apache-airflow-providers-amazon>=3.0.0; extra == "s3"
24
44
  Provides-Extra: snowflake
45
+ Requires-Dist: dbt-snowflake<2.0.0,>=1.8.0; extra == "snowflake"
25
46
  Provides-Extra: spark
26
- Requires-Dist: apache-airflow (>=2.8)
27
- Requires-Dist: apache-airflow-providers-amazon (>=3.0.0) ; extra == "airflow-providers"
28
- Requires-Dist: apache-airflow-providers-amazon (>=3.0.0) ; extra == "s3"
29
- Requires-Dist: apache-airflow-providers-google (>=11.0.0) ; extra == "airflow-providers"
30
- Requires-Dist: apache-airflow-providers-google (>=11.0.0) ; extra == "gcs"
31
- Requires-Dist: apache-airflow-providers-ssh (>=3.0.0) ; extra == "airflow-providers"
32
- Requires-Dist: apache-airflow-providers-ssh (>=3.0.0) ; extra == "git"
33
- Requires-Dist: contextlib-chdir (==1.0.2) ; python_version < "3.11"
34
- Requires-Dist: dbt-bigquery (>=1.8.0,<2.0.0) ; extra == "adapters"
35
- Requires-Dist: dbt-bigquery (>=1.8.0,<2.0.0) ; extra == "bigquery"
36
- Requires-Dist: dbt-core (>=1.8.0,<2.0.0)
37
- Requires-Dist: dbt-postgres (>=1.8.0,<2.0.0) ; extra == "adapters"
38
- Requires-Dist: dbt-postgres (>=1.8.0,<2.0.0) ; extra == "postgres"
39
- Requires-Dist: dbt-redshift (>=1.8.0,<2.0.0) ; extra == "adapters"
40
- Requires-Dist: dbt-redshift (>=1.8.0,<2.0.0) ; extra == "redshift"
41
- Requires-Dist: dbt-snowflake (>=1.8.0,<2.0.0) ; extra == "adapters"
42
- Requires-Dist: dbt-snowflake (>=1.8.0,<2.0.0) ; extra == "snowflake"
43
- Requires-Dist: dbt-spark (>=1.8.0,<2.0.0) ; extra == "spark"
44
- Requires-Dist: dbt-spark[all] (>=1.8.0,<2.0.0) ; extra == "adapters"
45
- Requires-Dist: dulwich (>=0.21) ; extra == "git"
46
- Description-Content-Type: text/markdown
47
+ Requires-Dist: dbt-spark<2.0.0,>=1.8.0; extra == "spark"
48
+ Dynamic: license-file
47
49
 
48
50
  # airflow-dbt-python
49
51
 
@@ -101,17 +103,17 @@ git clone https://github.com/tomasfarias/airflow-dbt-python.git
101
103
  cd airflow-dbt-python
102
104
  ```
103
105
 
104
- And installing with *Poetry*:
106
+ And installing with *uv*:
105
107
 
106
108
  ``` shell
107
- poetry install
109
+ uv pip install .
108
110
  ```
109
111
 
110
112
  ## In AWS MWAA
111
113
 
112
114
  Add *airflow-dbt-python* to your `requirements.txt` file and edit your Airflow environment to use this new `requirements.txt` file, or upload it as a plugin.
113
115
 
114
- Read the [documentation](https://airflow-dbt-python.readthedocs.io/en/latest/getting_started.html#installing-in-mwaa) for more a more detailed AWS MWAA installation breakdown.
116
+ Read the [documentation](https://airflow-dbt-python.readthedocs.io/en/latest/getting_started/#installing-in-mwaa) for more a more detailed AWS MWAA installation breakdown.
115
117
 
116
118
  ## In GCP Cloud Composer
117
119
 
@@ -245,7 +247,7 @@ with DAG(
245
247
  ) as dag:
246
248
  dbt_test = DbtTestOperator(
247
249
  task_id="dbt_test",
248
- selector_name="pre-run-tests",
250
+ selector="pre-run-tests",
249
251
  )
250
252
 
251
253
  dbt_seed = DbtSeedOperator(
@@ -268,17 +270,16 @@ More examples can be found in the [`examples/`](examples/) directory and the [do
268
270
 
269
271
  # Development
270
272
 
271
- See the [development documentation](https://airflow-dbt-python.readthedocs.io/en/latest/development.html) for a more in-depth dive into setting up a development environment, running the test-suite, and general commentary on working on *airflow-dbt-python*.
273
+ See the [development documentation](https://airflow-dbt-python.readthedocs.io/en/latest/development/) for a more in-depth dive into setting up a development environment, running the test-suite, and general commentary on working on *airflow-dbt-python*.
272
274
 
273
275
  ## Testing
274
276
 
275
- Tests are run with *pytest*, can be located in `tests/`. To run them locally, you may use *Poetry*:
277
+ Tests are run with *pytest*, can be located in `tests/`. To run them locally, you may use *uv*:
276
278
 
277
279
  ``` shell
278
- poetry run pytest tests/ -vv
280
+ uv run pytest tests/ -vv
279
281
  ```
280
282
 
281
283
  # License
282
284
 
283
285
  This project is licensed under the MIT license. See [LICENSE](LICENSE).
284
-
@@ -54,17 +54,17 @@ git clone https://github.com/tomasfarias/airflow-dbt-python.git
54
54
  cd airflow-dbt-python
55
55
  ```
56
56
 
57
- And installing with *Poetry*:
57
+ And installing with *uv*:
58
58
 
59
59
  ``` shell
60
- poetry install
60
+ uv pip install .
61
61
  ```
62
62
 
63
63
  ## In AWS MWAA
64
64
 
65
65
  Add *airflow-dbt-python* to your `requirements.txt` file and edit your Airflow environment to use this new `requirements.txt` file, or upload it as a plugin.
66
66
 
67
- Read the [documentation](https://airflow-dbt-python.readthedocs.io/en/latest/getting_started.html#installing-in-mwaa) for more a more detailed AWS MWAA installation breakdown.
67
+ Read the [documentation](https://airflow-dbt-python.readthedocs.io/en/latest/getting_started/#installing-in-mwaa) for more a more detailed AWS MWAA installation breakdown.
68
68
 
69
69
  ## In GCP Cloud Composer
70
70
 
@@ -198,7 +198,7 @@ with DAG(
198
198
  ) as dag:
199
199
  dbt_test = DbtTestOperator(
200
200
  task_id="dbt_test",
201
- selector_name="pre-run-tests",
201
+ selector="pre-run-tests",
202
202
  )
203
203
 
204
204
  dbt_seed = DbtSeedOperator(
@@ -221,14 +221,14 @@ More examples can be found in the [`examples/`](examples/) directory and the [do
221
221
 
222
222
  # Development
223
223
 
224
- See the [development documentation](https://airflow-dbt-python.readthedocs.io/en/latest/development.html) for a more in-depth dive into setting up a development environment, running the test-suite, and general commentary on working on *airflow-dbt-python*.
224
+ See the [development documentation](https://airflow-dbt-python.readthedocs.io/en/latest/development/) for a more in-depth dive into setting up a development environment, running the test-suite, and general commentary on working on *airflow-dbt-python*.
225
225
 
226
226
  ## Testing
227
227
 
228
- Tests are run with *pytest*, can be located in `tests/`. To run them locally, you may use *Poetry*:
228
+ Tests are run with *pytest*, can be located in `tests/`. To run them locally, you may use *uv*:
229
229
 
230
230
  ``` shell
231
- poetry run pytest tests/ -vv
231
+ uv run pytest tests/ -vv
232
232
  ```
233
233
 
234
234
  # License
@@ -3,4 +3,4 @@
3
3
  __author__ = "Tomás Farías Santana"
4
4
  __copyright__ = "Copyright 2021 Tomás Farías Santana"
5
5
  __title__ = "airflow-dbt-python"
6
- __version__ = "3.0.0"
6
+ __version__ = "3.0.3"
@@ -0,0 +1 @@
1
+ """The hooks module provides Airflow hooks used to interact with dbt."""
@@ -1,4 +1,8 @@
1
- """Provides a hook to interact with a dbt project."""
1
+ """Provides a hook to interact with dbt.
2
+
3
+ Interacting with dbt mainly means setting up a dbt project and running a dbt
4
+ task.
5
+ """
2
6
 
3
7
  from __future__ import annotations
4
8
 
@@ -1,8 +1,7 @@
1
- """The DbtFSHook interface includes methods for downloading and uploading files.
1
+ """A ``DbtFSHook`` can download and upload dbt project files to a filesystem.
2
2
 
3
- Internally, DbtFSHooks can use Airflow hooks to execute the actual operations.
4
-
5
- Currently, only AWS S3 and the local filesystem are supported as remotes.
3
+ By filesystem we understand any storage that can hold dbt project files, like an
4
+ S3 bucket or a git repository.
6
5
  """
7
6
 
8
7
  from abc import ABC, abstractmethod
@@ -1,7 +1,14 @@
1
- """Provides a hook to get a dbt profile based on the Airflow connection."""
1
+ """Provides hooks to establish a dbt connection with supported targets.
2
+
3
+ The connection details will be extracted from an Airflow connection, and each
4
+ target can interpret connection information differently according to its
5
+ specific connection requirements.
6
+ """
2
7
 
3
8
  from __future__ import annotations
4
9
 
10
+ import base64
11
+ import binascii
5
12
  import json
6
13
  import operator
7
14
  import re
@@ -21,6 +28,24 @@ from airflow.hooks.base import BaseHook
21
28
  from airflow.models.connection import Connection
22
29
 
23
30
 
31
+ def try_decode_base64(s: str) -> str:
32
+ """Attempt to decode a string from base64.
33
+
34
+ If the string is not valid base64, returns the original value.
35
+
36
+ Args:
37
+ s: The string to decode.
38
+
39
+ Returns:
40
+ The decoded string, or the original value if decoding fails.
41
+ """
42
+ try:
43
+ s = base64.b64decode(s, validate=True).decode("utf-8")
44
+ except binascii.Error:
45
+ pass
46
+ return s
47
+
48
+
24
49
  class DbtConnectionParam(NamedTuple):
25
50
  """A tuple indicating connection parameters relevant to dbt.
26
51
 
@@ -35,6 +60,7 @@ class DbtConnectionParam(NamedTuple):
35
60
  name: str
36
61
  store_override_name: Optional[str] = None
37
62
  default: Optional[Any] = None
63
+ converter: Callable[[Any], Any] | None = None
38
64
 
39
65
  @property
40
66
  def override_name(self):
@@ -225,6 +251,8 @@ class DbtConnectionHook(BaseHook, ABC, metaclass=DbtConnectionHookMeta):
225
251
  if isinstance(param, DbtConnectionParam):
226
252
  key = param.override_name
227
253
  value = getattr(conn, param.name, param.default)
254
+ if param.converter:
255
+ value = param.converter(value)
228
256
  elif isinstance(param, DbtConnectionConditionParam):
229
257
  key, default = param.resolve(conn)
230
258
  value = getattr(conn, param.name, default)
@@ -394,7 +422,9 @@ class DbtSnowflakeHook(DbtConnectionHook):
394
422
  "database",
395
423
  DbtConnectionParam("refresh_token", "token"),
396
424
  DbtConnectionParam("private_key_file", "private_key_path"),
397
- DbtConnectionParam("private_key_content", "private_key"),
425
+ DbtConnectionParam(
426
+ "private_key_content", "private_key", converter=try_decode_base64
427
+ ),
398
428
  ]
399
429
 
400
430
 
@@ -400,14 +400,15 @@ class DbtRunOperator(DbtBaseOperator):
400
400
  full_refresh: Optional[bool] = None,
401
401
  models: Optional[list[str]] = None,
402
402
  select: Optional[list[str]] = None,
403
- selector_name: Optional[list[str]] = None,
403
+ selector: Optional[str] = None,
404
+ selector_name: Optional[str] = None,
404
405
  exclude: Optional[list[str]] = None,
405
406
  **kwargs,
406
407
  ) -> None:
407
408
  super().__init__(**kwargs)
408
409
  self.full_refresh = full_refresh
409
410
  self.exclude = exclude
410
- self.selector_name = selector_name
411
+ self.selector = selector or selector_name
411
412
  self.select = select or models
412
413
 
413
414
  @property
@@ -432,6 +433,7 @@ class DbtSeedOperator(DbtBaseOperator):
432
433
  select: Optional[list[str]] = None,
433
434
  show: Optional[bool] = None,
434
435
  exclude: Optional[list[str]] = None,
436
+ selector: Optional[str] = None,
435
437
  selector_name: Optional[str] = None,
436
438
  **kwargs,
437
439
  ) -> None:
@@ -440,7 +442,7 @@ class DbtSeedOperator(DbtBaseOperator):
440
442
  self.select = select
441
443
  self.show = show
442
444
  self.exclude = exclude
443
- self.selector_name = selector_name
445
+ self.selector = selector or selector_name
444
446
 
445
447
  @property
446
448
  def command(self) -> str:
@@ -465,6 +467,7 @@ class DbtTestOperator(DbtBaseOperator):
465
467
  models: Optional[list[str]] = None,
466
468
  select: Optional[list[str]] = None,
467
469
  exclude: Optional[list[str]] = None,
470
+ selector: Optional[str] = None,
468
471
  selector_name: Optional[str] = None,
469
472
  indirect_selection: Optional[str] = None,
470
473
  **kwargs,
@@ -473,7 +476,7 @@ class DbtTestOperator(DbtBaseOperator):
473
476
  self.singular = singular
474
477
  self.generic = generic
475
478
  self.exclude = exclude
476
- self.selector_name = selector_name
479
+ self.selector = selector or selector_name
477
480
  self.select = select or models
478
481
  self.indirect_selection = indirect_selection
479
482
 
@@ -500,6 +503,7 @@ class DbtCompileOperator(_GraphRunnableOperator):
500
503
  models: Optional[list[str]] = None,
501
504
  select: Optional[list[str]] = None,
502
505
  exclude: Optional[list[str]] = None,
506
+ selector: Optional[str] = None,
503
507
  selector_name: Optional[str] = None,
504
508
  upload_dbt_project: bool = True,
505
509
  **kwargs,
@@ -508,7 +512,7 @@ class DbtCompileOperator(_GraphRunnableOperator):
508
512
  self.parse_only = parse_only
509
513
  self.full_refresh = full_refresh
510
514
  self.exclude = exclude
511
- self.selector_name = selector_name
515
+ self.selector = selector or selector_name
512
516
  self.select = select or models
513
517
  self.upload_dbt_project = upload_dbt_project
514
518
 
@@ -614,13 +618,14 @@ class DbtSnapshotOperator(DbtBaseOperator):
614
618
  self,
615
619
  select: Optional[list[str]] = None,
616
620
  exclude: Optional[list[str]] = None,
621
+ selector: Optional[str] = None,
617
622
  selector_name: Optional[str] = None,
618
623
  **kwargs,
619
624
  ) -> None:
620
625
  super().__init__(**kwargs)
621
626
  self.select = select
622
627
  self.exclude = exclude
623
- self.selector_name = selector_name
628
+ self.selector = selector or selector_name
624
629
 
625
630
  @property
626
631
  def command(self) -> str:
@@ -644,6 +649,7 @@ class DbtLsOperator(_GraphRunnableOperator):
644
649
  resource_types: Optional[list[str]] = None,
645
650
  select: Optional[list[str]] = None,
646
651
  exclude: Optional[list[str]] = None,
652
+ selector: Optional[str] = None,
647
653
  selector_name: Optional[str] = None,
648
654
  dbt_output: Optional[Output] = None,
649
655
  output_keys: Optional[list[str]] = None,
@@ -654,7 +660,7 @@ class DbtLsOperator(_GraphRunnableOperator):
654
660
  self.resource_types = resource_types
655
661
  self.select = select
656
662
  self.exclude = exclude
657
- self.selector_name = selector_name
663
+ self.selector = selector or selector_name
658
664
  self.dbt_output = dbt_output
659
665
  self.output_keys = output_keys
660
666
  self.indirect_selection = indirect_selection
@@ -727,6 +733,7 @@ class DbtSourceFreshnessOperator(DbtBaseOperator):
727
733
  select: Optional[list[str]] = None,
728
734
  dbt_output: Optional[Union[str, Path]] = None,
729
735
  exclude: Optional[list[str]] = None,
736
+ selector: Optional[str] = None,
730
737
  selector_name: Optional[str] = None,
731
738
  upload_dbt_project: bool = True,
732
739
  **kwargs,
@@ -734,7 +741,7 @@ class DbtSourceFreshnessOperator(DbtBaseOperator):
734
741
  super().__init__(**kwargs)
735
742
  self.select = select
736
743
  self.exclude = exclude
737
- self.selector_name = selector_name
744
+ self.selector = selector or selector_name
738
745
  self.dbt_output = dbt_output
739
746
  self.upload_dbt_project = upload_dbt_project
740
747
 
@@ -759,6 +766,7 @@ class DbtBuildOperator(DbtBaseOperator):
759
766
  full_refresh: Optional[bool] = None,
760
767
  select: Optional[list[str]] = None,
761
768
  exclude: Optional[list[str]] = None,
769
+ selector: Optional[str] = None,
762
770
  selector_name: Optional[str] = None,
763
771
  singular: Optional[bool] = None,
764
772
  generic: Optional[bool] = None,
@@ -770,7 +778,7 @@ class DbtBuildOperator(DbtBaseOperator):
770
778
  self.full_refresh = full_refresh
771
779
  self.select = select
772
780
  self.exclude = exclude
773
- self.selector_name = selector_name
781
+ self.selector = selector or selector_name
774
782
  self.singular = singular
775
783
  self.generic = generic
776
784
  self.show = show
@@ -181,14 +181,18 @@ class BaseConfig:
181
181
 
182
182
  # legacy behaviors - https://github.com/dbt-labs/dbt-core/blob/main/docs/guides/behavior-change-flags.md
183
183
  require_batched_execution_for_custom_microbatch_strategy: bool = False
184
+ require_event_names_in_deprecations: bool = False
184
185
  require_explicit_package_overrides_for_builtin_materializations: bool = True
185
- require_resource_names_without_spaces: bool = False
186
- source_freshness_run_project_hooks: bool = False
186
+ require_resource_names_without_spaces: bool = True
187
+ source_freshness_run_project_hooks: bool = True
187
188
  skip_nodes_if_on_run_start_fails: bool = False
188
189
  state_modified_compare_more_unrendered_values: bool = False
189
190
  state_modified_compare_vars: bool = False
190
191
  require_yaml_configuration_for_mf_time_spines: bool = False
191
192
  require_nested_cumulative_type_params: bool = False
193
+ validate_macro_args: bool = False
194
+ require_all_warnings_handled_by_warn_error: bool = False
195
+ require_generic_test_arguments_property: bool = False
192
196
 
193
197
  def __post_init__(self):
194
198
  """Post initialization actions for a dbt configuration."""
@@ -518,11 +522,13 @@ class SelectionConfig(BaseConfig):
518
522
 
519
523
  exclude: Optional[list[str]] = None
520
524
  select: Optional[list[str]] = None
521
- selector_name: Optional[list[str]] = None
522
525
  selector: Optional[str] = None
523
526
  state: Optional[Union[Path, str]] = None
524
527
  defer_state: Optional[Union[Path, str]] = None
525
528
 
529
+ # Kept for compatibility with dbt versions < 1.5
530
+ selector_name: Optional[str] = None
531
+
526
532
  # Kept for compatibility with dbt versions < 0.21
527
533
  models: Optional[list[str]] = None
528
534
 
@@ -0,0 +1,285 @@
1
+ Metadata-Version: 2.4
2
+ Name: airflow-dbt-python
3
+ Version: 3.0.3
4
+ Summary: A collection of Airflow operators, hooks, and utilities to execute dbt commands
5
+ Author-email: Tomás Farías Santana <tomas@tomasfarias.dev>
6
+ License-Expression: MIT
7
+ Project-URL: repository, https://github.com/tomasfarias/airflow-dbt-python
8
+ Project-URL: documentation, https://airflow-dbt-python.readthedocs.io
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: <3.13,>=3.9
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: apache-airflow>=2.8
19
+ Requires-Dist: contextlib-chdir==1.0.2; python_version < "3.11"
20
+ Requires-Dist: dbt-core<2.0.0,>=1.8.0
21
+ Provides-Extra: airflow-providers
22
+ Requires-Dist: apache-airflow-providers-amazon>=3.0.0; extra == "airflow-providers"
23
+ Requires-Dist: apache-airflow-providers-google>=11.0.0; extra == "airflow-providers"
24
+ Requires-Dist: apache-airflow-providers-ssh>=3.0.0; extra == "airflow-providers"
25
+ Provides-Extra: adapters
26
+ Requires-Dist: dbt-bigquery<2.0.0,>=1.8.0; extra == "adapters"
27
+ Requires-Dist: dbt-redshift<2.0.0,>=1.8.0; extra == "adapters"
28
+ Requires-Dist: dbt-postgres<2.0.0,>=1.8.0; extra == "adapters"
29
+ Requires-Dist: dbt-snowflake<2.0.0,>=1.8.0; extra == "adapters"
30
+ Requires-Dist: dbt-spark[all]<2.0.0,>=1.8.0; extra == "adapters"
31
+ Provides-Extra: bigquery
32
+ Requires-Dist: dbt-bigquery<2.0.0,>=1.8.0; extra == "bigquery"
33
+ Provides-Extra: gcs
34
+ Requires-Dist: apache-airflow-providers-google>=11.0.0; extra == "gcs"
35
+ Provides-Extra: git
36
+ Requires-Dist: apache-airflow-providers-ssh>=3.0.0; extra == "git"
37
+ Requires-Dist: dulwich>=0.21; extra == "git"
38
+ Provides-Extra: postgres
39
+ Requires-Dist: dbt-postgres<2.0.0,>=1.8.0; extra == "postgres"
40
+ Provides-Extra: redshift
41
+ Requires-Dist: dbt-redshift<2.0.0,>=1.8.0; extra == "redshift"
42
+ Provides-Extra: s3
43
+ Requires-Dist: apache-airflow-providers-amazon>=3.0.0; extra == "s3"
44
+ Provides-Extra: snowflake
45
+ Requires-Dist: dbt-snowflake<2.0.0,>=1.8.0; extra == "snowflake"
46
+ Provides-Extra: spark
47
+ Requires-Dist: dbt-spark<2.0.0,>=1.8.0; extra == "spark"
48
+ Dynamic: license-file
49
+
50
+ # airflow-dbt-python
51
+
52
+ [![PyPI version](https://img.shields.io/pypi/v/airflow-dbt-python?style=plastic)](https://pypi.org/project/airflow-dbt-python/)
53
+ [![CI testing](https://github.com/tomasfarias/airflow-dbt-python/actions/workflows/ci.yaml/badge.svg)](https://github.com/tomasfarias/airflow-dbt-python/actions)
54
+ [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
55
+ [![Test coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/tomasfarias/81ef37701aa088d18db8a58ce07c79c7/raw/covbadge.json)](https://github.com/tomasfarias/airflow-dbt-python/actions)
56
+ [![Documentation](https://readthedocs.org/projects/airflow-dbt-python/badge/?version=latest)](https://airflow-dbt-python.readthedocs.io/en/latest/?badge=latest)
57
+
58
+ A collection of [Airflow](https://airflow.apache.org/) operators, hooks, and utilities to execute [`dbt`](https://pypi.org/project/dbt-core/) commands.
59
+
60
+ Read the [documentation](https://airflow-dbt-python.readthedocs.io) for examples, installation instructions, and more details.
61
+
62
+ # Installation
63
+
64
+ ## Requirements
65
+
66
+ Before using *airflow-dbt-python*, ensure you meet the following requirements:
67
+ * A *dbt* project using [dbt-core](https://pypi.org/project/dbt-core/) version 1.8 or later.
68
+ * An Airflow environment using version 2.8 or later.
69
+
70
+ * If using any managed service, like AWS MWAA or GCP Cloud Composer 2/3, ensure your environment is created with a supported version of Airflow.
71
+ * If self-hosting, Airflow installation instructions can be found in their [official documentation](https://airflow.apache.org/docs/apache-airflow/stable/installation/index.html).
72
+
73
+ * Running Python 3.9 or later in your Airflow environment.
74
+
75
+ > **Warning**
76
+ >
77
+ > Even though we don't impose any upper limits on versions of Airflow and *dbt*, it's possible that new versions are not supported immediately after release, particularly for *dbt*. We recommend testing the latest versions before upgrading and [reporting any issues](https://github.com/tomasfarias/airflow-dbt-python/issues/new/choose).
78
+
79
+ > **Note**
80
+ >
81
+ > Older versions of Airflow and *dbt* may work with *airflow-dbt-python*, although we cannot guarantee this. Our testing pipeline runs the latest *dbt-core* with the latest Airflow release, and the latest version supported by [AWS MWAA](https://aws.amazon.com/managed-workflows-for-apache-airflow/) and [GCP Cloud Composer 2/3](https://aws.amazon.com/managed-workflows-for-apache-airflow/).
82
+
83
+ ## From PyPI
84
+
85
+ *airflow-dbt-python* is available in [PyPI](https://pypi.org/project/airflow-dbt-python/) and can be installed with *pip*:
86
+
87
+ ``` shell
88
+ pip install airflow-dbt-python
89
+ ```
90
+
91
+ As a convenience, some *dbt* adapters can be installed by specifying extras. For example, if requiring the *dbt-redshift* adapter:
92
+
93
+ ``` shell
94
+ pip install airflow-dbt-python[redshift]
95
+ ```
96
+
97
+ ## From this repo
98
+
99
+ *airflow-dbt-python* can also be built from source by cloning this GitHub repository:
100
+
101
+ ``` shell
102
+ git clone https://github.com/tomasfarias/airflow-dbt-python.git
103
+ cd airflow-dbt-python
104
+ ```
105
+
106
+ And installing with *uv*:
107
+
108
+ ``` shell
109
+ uv pip install .
110
+ ```
111
+
112
+ ## In AWS MWAA
113
+
114
+ Add *airflow-dbt-python* to your `requirements.txt` file and edit your Airflow environment to use this new `requirements.txt` file, or upload it as a plugin.
115
+
116
+ Read the [documentation](https://airflow-dbt-python.readthedocs.io/en/latest/getting_started/#installing-in-mwaa) for more a more detailed AWS MWAA installation breakdown.
117
+
118
+ ## In GCP Cloud Composer
119
+
120
+ Add *airflow-dbt-python* to your PyPI packages list.
121
+
122
+ Read the [documentation](https://cloud.google.com/composer/docs/composer-2/install-python-dependencies#install-pypi) for more a more detailed GCP Cloud Composer 2 installation breakdown.
123
+
124
+ ## In other managed services
125
+
126
+ *airflow-dbt-python* should be compatible with most or all Airflow managed services. Consult the documentation specific to your provider.
127
+
128
+ If you notice an issue when installing *airflow-dbt-python* in a specific managed service, please open an [issue](https://github.com/tomasfarias/airflow-dbt-python/issues/new/choose).
129
+
130
+ # Features
131
+
132
+ *airflow-dbt-python* aims to make dbt a **first-class citizen** of Airflow by supporting additional features that integrate both tools. As you would expect, *airflow-dbt-python* can run all your dbt workflows in Airflow with the same interface you are used to from the CLI, but without being a mere wrapper: *airflow-dbt-python* directly communicates with internal *dbt-core* classes, bridging the gap between them and Airflow's operator interface. Essentially, we are attempting to use *dbt* **as a library**.
133
+
134
+ As this integration was completed, several features were developed to **extend the capabilities of dbt** to leverage Airflow as much as possible. Can you think of a way *dbt* could leverage Airflow that is not currently supported? Let us know in a [GitHub issue](https://github.com/tomasfarias/airflow-dbt-python/issues/new/choose)!
135
+
136
+ ## Independent task execution
137
+
138
+ Airflow executes [Tasks](https://airflow.apache.org/docs/apache-airflow/stable/concepts/tasks.html) independent of one another: even though downstream and upstream dependencies between tasks exist, the execution of an individual task happens entirely independently of any other task execution (see: [Tasks Relationships](https://airflow.apache.org/docs/apache-airflow/stable/concepts/tasks.html#relationships)).
139
+
140
+ In order to work with this constraint, *airflow-dbt-python* runs each dbt command in a **temporary and isolated directory**. Before execution, all the relevant dbt files are copied from supported backends, and after executing the command any artifacts are exported. This ensures dbt can work with any Airflow deployment, including most production deployments as they are usually running [Remote Executors](https://airflow.apache.org/docs/apache-airflow/stable/executor/index.html#executor-types) and do not guarantee any files will be shared by default between tasks, since each task may run in a completely different environment.
141
+
142
+
143
+ ## Download dbt files from a remote storage
144
+
145
+ The dbt parameters `profiles_dir` and `project_dir` would normally point to a directory containing a `profiles.yml` file and a dbt project in the local environment respectively (defined by the presence of a *dbt_project.yml* file). *airflow-dbt-python* extends these parameters to also accept an URL pointing to a remote storage.
146
+
147
+ Currently, we support the following remote storages:
148
+
149
+ * [AWS S3](https://aws.amazon.com/s3/) (identified by a *s3* scheme).
150
+ * Remote git repositories, like those stored in GitHub (both *https* and *ssh* schemes are supported).
151
+
152
+ * If a remote URL is used for `project_dir`, then this URL must point to a location in your remote storage containing a *dbt* project to run. A *dbt* project is identified by the prescence of a *dbt_project.yml*, and contains all your [resources](https://docs.getdbt.com/docs/build/projects). All of the contents of this remote location will be downloaded and made available for the operator. The URL may also point to an archived file containing all the files of a dbt project, which will be downloaded, uncompressed, and made available for the operator.
153
+ * If a remote URL is used for `profiles_dir`, then this URL must point to a location in your remote storage that contains a *profiles.yml* file. The *profiles.yml* file will be downloaded and made available for the operator to use when running. The *profiles.yml* may be part of your *dbt* project, in which case this argument may be ommitted.
154
+
155
+ This feature is intended to work in line with Airflow's [description of the task concept](https://airflow.apache.org/docs/apache-airflow/stable/concepts/tasks.html#relationships):
156
+
157
+ > Tasks don’t pass information to each other by default, and run entirely independently.
158
+
159
+ We interpret this as meaning a task should be responsible of fetching all the *dbt* related files it needs in order to run independently, as already described in [Independent Task Execution](#independent-task-execution).
160
+
161
+ ## Push dbt artifacts to XCom
162
+
163
+ Each dbt execution produces one or more [JSON artifacts](https://docs.getdbt.com/reference/artifacts/dbt-artifacts/) that are valuable to produce meta-metrics, build conditional workflows, for reporting purposes, and other uses. *airflow-dbt-python* can push these artifacts to [XCom](https://airflow.apache.org/docs/apache-airflow/stable/concepts/xcoms.html) as requested via the `do_xcom_push_artifacts` parameter, which takes a list of artifacts to push.
164
+
165
+ ## Use Airflow connections as dbt targets (without a profiles.yml)
166
+
167
+ [Airflow connections](https://airflow.apache.org/docs/apache-airflow/stable/howto/connection.html) allow users to manage and store connection information, such as hostname, port, username, and password, for operators to use when accessing certain applications, like databases. Similarly, a *dbt* `profiles.yml` file stores connection information under each target key. *airflow-dbt-python* bridges the gap between the two and allows you to use connection information stored as an Airflow connection by specifying the connection id as the `target` parameter of any of the *dbt* operators it provides. What's more, if using an Airflow connection, the `profiles.yml` file may be entirely omitted (although keep in mind a `profiles.yml` file contains a configuration block besides target connection information).
168
+
169
+ See an example DAG [here](examples/airflow_connection_target_dag.py).
170
+
171
+ # Motivation
172
+
173
+ ## Airflow running in a managed environment
174
+
175
+ Although [`dbt`](https://docs.getdbt.com/) is meant to be installed and used as a CLI, we may not have control of the environment where Airflow is running, disallowing us the option of using *dbt* as a CLI.
176
+
177
+ This is exactly what happens when using [Amazon's Managed Workflows for Apache Airflow](https://aws.amazon.com/managed-workflows-for-apache-airflow/) (aka MWAA): although a list of Python requirements can be passed, the CLI cannot be found in the worker's PATH.
178
+
179
+ There is a workaround which involves using Airflow's `BashOperator` and running Python from the command line:
180
+
181
+ ``` python
182
+ from airflow.operators.bash import BashOperator
183
+
184
+ BASH_COMMAND = "python -c 'from dbt.main import main; main()' run"
185
+ operator = BashOperator(
186
+ task_id="dbt_run",
187
+ bash_command=BASH_COMMAND,
188
+ )
189
+ ```
190
+
191
+ But it can get cumbersome when appending all potential arguments a `dbt run` command (or other subcommand) can take.
192
+
193
+ That's where *airflow-dbt-python* comes in: it abstracts the complexity of interfacing with *dbt-core* and exposes one operator for each *dbt* subcommand that can be instantiated with all the corresponding arguments that the *dbt* CLI would take.
194
+
195
+ ## An alternative to *airflow-dbt* that works without the *dbt* CLI
196
+
197
+ The alternative [`airflow-dbt`](https://pypi.org/project/airflow-dbt/) package, by default, would not work if the *dbt* CLI is not in PATH, which means it would not be usable in MWAA. There is a workaround via the `dbt_bin` argument, which can be set to `"python -c 'from dbt.main import main; main()' run"`, in similar fashion as the `BashOperator` example. Yet this approach is not without its limitations:
198
+ * *airflow-dbt* works by wrapping the *dbt* CLI, which makes our code dependent on the environment in which it runs.
199
+ * *airflow-dbt* does not support the full range of arguments a command can take. For example, `DbtRunOperator` does not have an attribute for `fail_fast`.
200
+ * *airflow-dbt* does not offer access to *dbt* artifacts created during execution. *airflow-dbt-python* does so by pushing any artifacts to [XCom](https://airflow.apache.org/docs/apache-airflow/stable/concepts/xcoms.html).
201
+
202
+ # Usage
203
+
204
+ Currently, the following *dbt* commands are supported:
205
+
206
+ * `clean`
207
+ * `compile`
208
+ * `debug`
209
+ * `deps`
210
+ * `docs generate`
211
+ * `ls`
212
+ * `parse`
213
+ * `run`
214
+ * `run-operation`
215
+ * `seed`
216
+ * `snapshot`
217
+ * `source`
218
+ * `test`
219
+
220
+ ## Examples
221
+
222
+ All example DAGs are tested against the latest Airflow version. Some changes, like modifying `import` statements or changing types, may be required for them to work in other versions.
223
+
224
+ ``` python
225
+ import datetime as dt
226
+
227
+ import pendulum
228
+ from airflow import DAG
229
+
230
+ from airflow_dbt_python.operators.dbt import (
231
+ DbtRunOperator,
232
+ DbtSeedOperator,
233
+ DbtTestOperator,
234
+ )
235
+
236
+ args = {
237
+ "owner": "airflow",
238
+ }
239
+
240
+ with DAG(
241
+ dag_id="example_dbt_operator",
242
+ default_args=args,
243
+ schedule="0 0 * * *",
244
+ start_date=pendulum.today("UTC").add(days=-1),
245
+ dagrun_timeout=dt.timedelta(minutes=60),
246
+ tags=["example", "example2"],
247
+ ) as dag:
248
+ dbt_test = DbtTestOperator(
249
+ task_id="dbt_test",
250
+ selector="pre-run-tests",
251
+ )
252
+
253
+ dbt_seed = DbtSeedOperator(
254
+ task_id="dbt_seed",
255
+ select=["/path/to/first.csv", "/path/to/second.csv"],
256
+ full_refresh=True,
257
+ )
258
+
259
+ dbt_run = DbtRunOperator(
260
+ task_id="dbt_run",
261
+ select=["/path/to/models"],
262
+ full_refresh=True,
263
+ fail_fast=True,
264
+ )
265
+
266
+ dbt_test >> dbt_seed >> dbt_run
267
+ ```
268
+
269
+ More examples can be found in the [`examples/`](examples/) directory and the [documentation](https://airflow-dbt-python.readthedocs.io).
270
+
271
+ # Development
272
+
273
+ See the [development documentation](https://airflow-dbt-python.readthedocs.io/en/latest/development/) for a more in-depth dive into setting up a development environment, running the test-suite, and general commentary on working on *airflow-dbt-python*.
274
+
275
+ ## Testing
276
+
277
+ Tests are run with *pytest*, can be located in `tests/`. To run them locally, you may use *uv*:
278
+
279
+ ``` shell
280
+ uv run pytest tests/ -vv
281
+ ```
282
+
283
+ # License
284
+
285
+ This project is licensed under the MIT license. See [LICENSE](LICENSE).
@@ -0,0 +1,26 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ airflow_dbt_python/__init__.py
5
+ airflow_dbt_python/__version__.py
6
+ airflow_dbt_python.egg-info/PKG-INFO
7
+ airflow_dbt_python.egg-info/SOURCES.txt
8
+ airflow_dbt_python.egg-info/dependency_links.txt
9
+ airflow_dbt_python.egg-info/requires.txt
10
+ airflow_dbt_python.egg-info/top_level.txt
11
+ airflow_dbt_python/hooks/__init__.py
12
+ airflow_dbt_python/hooks/dbt.py
13
+ airflow_dbt_python/hooks/target.py
14
+ airflow_dbt_python/hooks/fs/__init__.py
15
+ airflow_dbt_python/hooks/fs/gcs.py
16
+ airflow_dbt_python/hooks/fs/git.py
17
+ airflow_dbt_python/hooks/fs/local.py
18
+ airflow_dbt_python/hooks/fs/s3.py
19
+ airflow_dbt_python/operators/__init__.py
20
+ airflow_dbt_python/operators/dbt.py
21
+ airflow_dbt_python/utils/__init__.py
22
+ airflow_dbt_python/utils/configs.py
23
+ airflow_dbt_python/utils/enums.py
24
+ airflow_dbt_python/utils/env.py
25
+ airflow_dbt_python/utils/url.py
26
+ airflow_dbt_python/utils/version.py
@@ -0,0 +1,42 @@
1
+ apache-airflow>=2.8
2
+ dbt-core<2.0.0,>=1.8.0
3
+
4
+ [:python_version < "3.11"]
5
+ contextlib-chdir==1.0.2
6
+
7
+ [adapters]
8
+ dbt-bigquery<2.0.0,>=1.8.0
9
+ dbt-redshift<2.0.0,>=1.8.0
10
+ dbt-postgres<2.0.0,>=1.8.0
11
+ dbt-snowflake<2.0.0,>=1.8.0
12
+ dbt-spark[all]<2.0.0,>=1.8.0
13
+
14
+ [airflow-providers]
15
+ apache-airflow-providers-amazon>=3.0.0
16
+ apache-airflow-providers-google>=11.0.0
17
+ apache-airflow-providers-ssh>=3.0.0
18
+
19
+ [bigquery]
20
+ dbt-bigquery<2.0.0,>=1.8.0
21
+
22
+ [gcs]
23
+ apache-airflow-providers-google>=11.0.0
24
+
25
+ [git]
26
+ apache-airflow-providers-ssh>=3.0.0
27
+ dulwich>=0.21
28
+
29
+ [postgres]
30
+ dbt-postgres<2.0.0,>=1.8.0
31
+
32
+ [redshift]
33
+ dbt-redshift<2.0.0,>=1.8.0
34
+
35
+ [s3]
36
+ apache-airflow-providers-amazon>=3.0.0
37
+
38
+ [snowflake]
39
+ dbt-snowflake<2.0.0,>=1.8.0
40
+
41
+ [spark]
42
+ dbt-spark<2.0.0,>=1.8.0
@@ -0,0 +1 @@
1
+ airflow_dbt_python
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "airflow-dbt-python"
3
- version = "3.0.1"
3
+ version = "3.0.3"
4
4
  description = "A collection of Airflow operators, hooks, and utilities to execute dbt commands"
5
5
  authors = [{ name = "Tomás Farías Santana", email = "tomas@tomasfarias.dev" }]
6
6
  license = "MIT"
@@ -11,8 +11,6 @@ classifiers = [
11
11
 
12
12
  "Intended Audience :: Developers",
13
13
 
14
- "License :: OSI Approved :: MIT License",
15
-
16
14
  "Programming Language :: Python :: 3.9",
17
15
  "Programming Language :: Python :: 3.10",
18
16
  "Programming Language :: Python :: 3.11",
@@ -25,12 +23,9 @@ dependencies = [
25
23
  "dbt-core>=1.8.0,<2.0.0",
26
24
  ]
27
25
 
28
- [project.url]
26
+ [project.urls]
29
27
  repository = "https://github.com/tomasfarias/airflow-dbt-python"
30
-
31
- [build-system]
32
- requires = ["poetry-core>=1.2.0"]
33
- build-backend = "poetry.core.masonry.api"
28
+ documentation = "https://airflow-dbt-python.readthedocs.io"
34
29
 
35
30
  [project.optional-dependencies]
36
31
  airflow-providers = [
@@ -71,62 +66,35 @@ spark = [
71
66
  "dbt-spark>=1.8.0,<2.0.0",
72
67
  ]
73
68
 
74
- [tool.poetry.requires-plugins]
75
- poetry-plugin-export = ">=1.8"
76
-
77
- [tool.poetry.group.dev]
78
- optional = true
79
-
80
- [tool.poetry.group.dev.dependencies]
81
- apache-airflow-providers-amazon = ">=3.0.0"
82
- apache-airflow-providers-google = ">=11.0.0"
83
- apache-airflow-providers-ssh = ">=3.0.0"
84
- black = ">=22"
85
- boto3-stubs = { extras = ["s3"], version = ">=1.26.8" }
86
- coverage = { extras = ["toml"], version = ">=7.2" }
87
- # docutils 0.21 causes an error with poetry (https://github.com/python-poetry/poetry/issues/9293)
88
- docutils = "!=0.21"
89
- dulwich = ">=0.21,!=0.21.6"
90
- moto = ">=4.0.3"
91
- mypy = ">=1"
92
- freezegun = ">=1.1.0"
93
- pre-commit = ">=2.18"
94
- pytest = ">=7.2"
95
- pytest-postgresql = ">=5"
96
- ruff = ">=0.0.254"
97
- types-freezegun = ">=1.1.6"
98
- types-PyYAML = ">=6.0.7"
99
- pytest-mock = "^3.14.0"
100
- mock-gcp = ">=0.2.0"
101
-
102
- [tool.poetry.group.docs]
103
- optional = true
104
-
105
- [tool.poetry.group.docs.dependencies]
106
- Sphinx = "7.4.7"
107
- sphinx-rtd-theme = "3.0.2"
108
- sphinx-copybutton = "0.5.2"
109
- attrs = ">=22"
110
- zipp = ">=3.19.1"
111
-
112
- [tool.black]
113
- line-length = 88
114
- target-version = ["py39", "py310", "py311", "py312"]
115
- include = '\.pyi?$'
116
- exclude = '''
117
- /(
118
- \.eggs
119
- | \.git
120
- | \.hg
121
- | \.mypy_cache
122
- | \.tox
123
- | \.venv
124
- | _build
125
- | buck-out
126
- | build
127
- | dist
128
- )/
129
- '''
69
+ [dependency-groups]
70
+ dev = [
71
+ "apache-airflow-providers-amazon>=3.0.0",
72
+ "apache-airflow-providers-google>=11.0.0",
73
+ "apache-airflow-providers-ssh>=3.0.0",
74
+ "boto3-stubs[s3]>=1.26.8",
75
+ "coverage[toml]>=7.2",
76
+ # docutils 0.21 causes an error with poetry (https://github.com/python-poetry/poetry/issues/9293)
77
+ "docutils!=0.21",
78
+ "dulwich>=0.21,!=0.21.6",
79
+ "freezegun>=1.1.0",
80
+ "mock-gcp==0.2.0",
81
+ "moto>=4.0.3",
82
+ "mypy>=1",
83
+ "pre-commit>=2.18",
84
+ "pytest>=7.2",
85
+ "pytest-mock>=3.14.0",
86
+ "pytest-postgresql>=5",
87
+ "ruff>=0.0.254",
88
+ "types-PyYAML>=6.0.7",
89
+ "types-freezegun>=1.1.6",
90
+ ]
91
+ docs = [
92
+ "attrs>=22",
93
+ "Sphinx==7.4.7",
94
+ "sphinx-copybutton==0.5.2",
95
+ "sphinx-rtd-theme==3.0.2",
96
+ "zipp>=3.19.1",
97
+ ]
130
98
 
131
99
  [tool.coverage.run]
132
100
  source = ["airflow_dbt_python"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1 +0,0 @@
1
- """Hooks module provides DbtHooks and DbtFSHooks."""