apache-airflow-providers-snowflake 6.5.4rc1__py3-none-any.whl → 6.6.0__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-snowflake might be problematic. Click here for more details.

@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "6.5.4"
32
+ __version__ = "6.6.0"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
35
  "2.10.0"
@@ -18,21 +18,11 @@
18
18
  from __future__ import annotations
19
19
 
20
20
  from collections.abc import Callable, Sequence
21
- from typing import TYPE_CHECKING
22
-
23
- from airflow.providers.snowflake.version_compat import AIRFLOW_V_3_0_PLUS
24
-
25
- if AIRFLOW_V_3_0_PLUS:
26
- from airflow.sdk.bases.decorator import DecoratedOperator, task_decorator_factory
27
- else:
28
- from airflow.decorators.base import DecoratedOperator, task_decorator_factory # type: ignore[no-redef]
29
21
 
22
+ from airflow.providers.common.compat.sdk import DecoratedOperator, TaskDecorator, task_decorator_factory
30
23
  from airflow.providers.snowflake.operators.snowpark import SnowparkOperator
31
24
  from airflow.providers.snowflake.utils.snowpark import inject_session_into_op_kwargs
32
25
 
33
- if TYPE_CHECKING:
34
- from airflow.sdk.bases.decorator import TaskDecorator
35
-
36
26
 
37
27
  class _SnowparkDecoratedOperator(DecoratedOperator, SnowparkOperator):
38
28
  """
@@ -73,11 +73,13 @@ def get_provider_info():
73
73
  "source-integration-name": "Google Cloud Storage (GCS)",
74
74
  "target-integration-name": "Snowflake",
75
75
  "python-module": "airflow.providers.snowflake.transfers.copy_into_snowflake",
76
+ "how-to-guide": "/docs/apache-airflow-providers-snowflake/operators/copy_into_snowflake.rst",
76
77
  },
77
78
  {
78
79
  "source-integration-name": "Microsoft Azure Blob Storage",
79
80
  "target-integration-name": "Snowflake",
80
81
  "python-module": "airflow.providers.snowflake.transfers.copy_into_snowflake",
82
+ "how-to-guide": "/docs/apache-airflow-providers-snowflake/operators/copy_into_snowflake.rst",
81
83
  },
82
84
  ],
83
85
  "connection-types": [
@@ -92,4 +94,18 @@ def get_provider_info():
92
94
  "python-modules": ["airflow.providers.snowflake.triggers.snowflake_trigger"],
93
95
  }
94
96
  ],
97
+ "config": {
98
+ "snowflake": {
99
+ "description": "Configuration for Snowflake hooks and operators.\n",
100
+ "options": {
101
+ "azure_oauth_scope": {
102
+ "description": "The scope to use while retrieving OAuth token for Snowflake from Azure Entra authentication.\n",
103
+ "version_added": "6.6.0",
104
+ "type": "string",
105
+ "example": None,
106
+ "default": "api://snowflake_oauth_server/.default",
107
+ }
108
+ },
109
+ }
110
+ },
95
111
  }
@@ -36,7 +36,9 @@ from snowflake.connector import DictCursor, SnowflakeConnection, util_text
36
36
  from snowflake.sqlalchemy import URL
37
37
  from sqlalchemy import create_engine
38
38
 
39
+ from airflow.configuration import conf
39
40
  from airflow.exceptions import AirflowException
41
+ from airflow.providers.common.compat.sdk import Connection
40
42
  from airflow.providers.common.sql.hooks.handlers import return_single_query_results
41
43
  from airflow.providers.common.sql.hooks.sql import DbApiHook
42
44
  from airflow.providers.snowflake.utils.openlineage import fix_snowflake_sqlalchemy_uri
@@ -94,6 +96,7 @@ class SnowflakeHook(DbApiHook):
94
96
  hook_name = "Snowflake"
95
97
  supports_autocommit = True
96
98
  _test_connection_sql = "select 1"
99
+ default_azure_oauth_scope = "api://snowflake_oauth_server/.default"
97
100
 
98
101
  @classmethod
99
102
  def get_connection_form_widgets(cls) -> dict[str, Any]:
@@ -246,6 +249,40 @@ class SnowflakeHook(DbApiHook):
246
249
  token = response.json()["access_token"]
247
250
  return token
248
251
 
252
+ def get_azure_oauth_token(self, azure_conn_id: str) -> str:
253
+ """
254
+ Generate OAuth access token using Azure connection id.
255
+
256
+ This uses AzureBaseHook on the connection id to retrieve the token. Scope for the OAuth token can be
257
+ set in the config option ``azure_oauth_scope`` under the section ``[snowflake]``.
258
+
259
+ :param azure_conn_id: The connection id for the Azure connection that will be used to fetch the token.
260
+ :raises AttributeError: If AzureBaseHook does not have a get_token method which happens when
261
+ package apache-airflow-providers-microsoft-azure<12.8.0.
262
+ :returns: The OAuth access token string.
263
+ """
264
+ if TYPE_CHECKING:
265
+ from airflow.providers.microsoft.azure.hooks.azure_base import AzureBaseHook
266
+
267
+ try:
268
+ azure_conn = Connection.get(azure_conn_id)
269
+ except AttributeError:
270
+ azure_conn = Connection.get_connection_from_secrets(azure_conn_id) # type: ignore[attr-defined]
271
+ azure_base_hook: AzureBaseHook = azure_conn.get_hook()
272
+ scope = conf.get("snowflake", "azure_oauth_scope", fallback=self.default_azure_oauth_scope)
273
+ try:
274
+ token = azure_base_hook.get_token(scope).token
275
+ except AttributeError as e:
276
+ if e.name == "get_token" and e.obj == azure_base_hook:
277
+ raise AttributeError(
278
+ "'AzureBaseHook' object has no attribute 'get_token'. "
279
+ "Please upgrade apache-airflow-providers-microsoft-azure>=12.8.0",
280
+ name=e.name,
281
+ obj=e.obj,
282
+ ) from e
283
+ raise
284
+ return token
285
+
249
286
  @cached_property
250
287
  def _get_conn_params(self) -> dict[str, str | None]:
251
288
  """
@@ -349,14 +386,17 @@ class SnowflakeHook(DbApiHook):
349
386
  conn_config["authenticator"] = "oauth"
350
387
 
351
388
  if conn_config.get("authenticator") == "oauth":
352
- token_endpoint = self._get_field(extra_dict, "token_endpoint") or ""
353
- conn_config["client_id"] = conn.login
354
- conn_config["client_secret"] = conn.password
355
- conn_config["token"] = self.get_oauth_token(
356
- conn_config=conn_config,
357
- token_endpoint=token_endpoint,
358
- grant_type=extra_dict.get("grant_type", "refresh_token"),
359
- )
389
+ if extra_dict.get("azure_conn_id"):
390
+ conn_config["token"] = self.get_azure_oauth_token(extra_dict["azure_conn_id"])
391
+ else:
392
+ token_endpoint = self._get_field(extra_dict, "token_endpoint") or ""
393
+ conn_config["client_id"] = conn.login
394
+ conn_config["client_secret"] = conn.password
395
+ conn_config["token"] = self.get_oauth_token(
396
+ conn_config=conn_config,
397
+ token_endpoint=token_endpoint,
398
+ grant_type=extra_dict.get("grant_type", "refresh_token"),
399
+ )
360
400
 
361
401
  conn_config.pop("login", None)
362
402
  conn_config.pop("user", None)
@@ -35,11 +35,7 @@ from airflow.providers.snowflake.hooks.snowflake_sql_api import SnowflakeSqlApiH
35
35
  from airflow.providers.snowflake.triggers.snowflake_trigger import SnowflakeSqlApiTrigger
36
36
 
37
37
  if TYPE_CHECKING:
38
- try:
39
- from airflow.sdk.definitions.context import Context
40
- except ImportError:
41
- # TODO: Remove once provider drops support for Airflow 2
42
- from airflow.utils.context import Context
38
+ from airflow.providers.common.compat.sdk import Context
43
39
 
44
40
 
45
41
  class SnowflakeCheckOperator(SQLCheckOperator):
@@ -22,9 +22,9 @@ from __future__ import annotations
22
22
  from collections.abc import Sequence
23
23
  from typing import Any
24
24
 
25
+ from airflow.providers.common.compat.sdk import BaseOperator
25
26
  from airflow.providers.snowflake.hooks.snowflake import SnowflakeHook
26
27
  from airflow.providers.snowflake.utils.common import enclose_param
27
- from airflow.providers.snowflake.version_compat import BaseOperator
28
28
 
29
29
 
30
30
  def _validate_parameter(param_name: str, value: str | None) -> str | None:
@@ -34,12 +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
39
- else:
40
- from airflow.models import BaseOperator
41
-
42
37
  __all__ = [
43
38
  "AIRFLOW_V_3_0_PLUS",
44
- "BaseOperator",
45
39
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apache-airflow-providers-snowflake
3
- Version: 6.5.4rc1
3
+ Version: 6.6.0
4
4
  Summary: Provider package apache-airflow-providers-snowflake for Apache Airflow
5
5
  Keywords: airflow-provider,snowflake,airflow,integration
6
6
  Author-email: Apache Software Foundation <dev@airflow.apache.org>
@@ -20,25 +20,27 @@ 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
25
- Requires-Dist: apache-airflow-providers-common-sql>=1.27.5rc1
23
+ Requires-Dist: apache-airflow>=2.10.0
24
+ Requires-Dist: apache-airflow-providers-common-compat>=1.8.0
25
+ Requires-Dist: apache-airflow-providers-common-sql>=1.27.5
26
26
  Requires-Dist: pandas>=2.1.2; python_version <"3.13"
27
27
  Requires-Dist: pandas>=2.2.3; python_version >="3.13"
28
28
  Requires-Dist: pyarrow>=16.1.0; python_version < '3.13'
29
29
  Requires-Dist: pyarrow>=18.0.0; python_version >= '3.13'
30
30
  Requires-Dist: snowflake-connector-python>=3.7.1
31
31
  Requires-Dist: snowflake-sqlalchemy>=1.4.0
32
- Requires-Dist: snowflake-snowpark-python>=1.17.0;python_version<'3.12'
33
- Requires-Dist: snowflake-snowpark-python>=1.27.0,<9999;python_version>='3.12' and python_version<'3.13'
34
- Requires-Dist: apache-airflow-providers-openlineage>=2.3.0rc1 ; extra == "openlineage"
32
+ Requires-Dist: snowflake-snowpark-python>=1.17.0,<9999;python_version<'3.12'
33
+ Requires-Dist: snowflake-snowpark-python>=1.27.0,<9999;python_version>='3.12' and python_version<'3.14'
34
+ Requires-Dist: apache-airflow-providers-microsoft-azure ; extra == "microsoft-azure"
35
+ Requires-Dist: apache-airflow-providers-openlineage>=2.3.0 ; extra == "openlineage"
35
36
  Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
36
- Project-URL: Changelog, https://airflow.staged.apache.org/docs/apache-airflow-providers-snowflake/6.5.4/changelog.html
37
- Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-snowflake/6.5.4
37
+ Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.6.0/changelog.html
38
+ Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.6.0
38
39
  Project-URL: Mastodon, https://fosstodon.org/@airflow
39
40
  Project-URL: Slack Chat, https://s.apache.org/airflow-slack
40
41
  Project-URL: Source Code, https://github.com/apache/airflow
41
42
  Project-URL: YouTube, https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/
43
+ Provides-Extra: microsoft-azure
42
44
  Provides-Extra: openlineage
43
45
 
44
46
 
@@ -66,7 +68,7 @@ Provides-Extra: openlineage
66
68
 
67
69
  Package ``apache-airflow-providers-snowflake``
68
70
 
69
- Release: ``6.5.4``
71
+ Release: ``6.6.0``
70
72
 
71
73
 
72
74
  `Snowflake <https://www.snowflake.com/>`__
@@ -79,7 +81,7 @@ This is a provider package for ``snowflake`` provider. All classes for this prov
79
81
  are in ``airflow.providers.snowflake`` python package.
80
82
 
81
83
  You can find package information and changelog for the provider
82
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.5.4/>`_.
84
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.6.0/>`_.
83
85
 
84
86
  Installation
85
87
  ------------
@@ -97,7 +99,7 @@ Requirements
97
99
  PIP package Version required
98
100
  ========================================== ========================================================================
99
101
  ``apache-airflow`` ``>=2.10.0``
100
- ``apache-airflow-providers-common-compat`` ``>=1.6.0``
102
+ ``apache-airflow-providers-common-compat`` ``>=1.8.0``
101
103
  ``apache-airflow-providers-common-sql`` ``>=1.27.5``
102
104
  ``pandas`` ``>=2.1.2; python_version < "3.13"``
103
105
  ``pandas`` ``>=2.2.3; python_version >= "3.13"``
@@ -105,8 +107,8 @@ PIP package Version required
105
107
  ``pyarrow`` ``>=18.0.0; python_version >= "3.13"``
106
108
  ``snowflake-connector-python`` ``>=3.7.1``
107
109
  ``snowflake-sqlalchemy`` ``>=1.4.0``
108
- ``snowflake-snowpark-python`` ``>=1.17.0; python_version < "3.12"``
109
- ``snowflake-snowpark-python`` ``>=1.27.0,<9999; python_version >= "3.12" and python_version < "3.13"``
110
+ ``snowflake-snowpark-python`` ``>=1.17.0,<9999; python_version < "3.12"``
111
+ ``snowflake-snowpark-python`` ``>=1.27.0,<9999; python_version >= "3.12" and python_version < "3.14"``
110
112
  ========================================== ========================================================================
111
113
 
112
114
  Cross provider package dependencies
@@ -122,23 +124,25 @@ You can install such cross-provider dependencies when installing from PyPI. For
122
124
  pip install apache-airflow-providers-snowflake[common.compat]
123
125
 
124
126
 
125
- ================================================================================================================== =================
126
- Dependent package Extra
127
- ================================================================================================================== =================
128
- `apache-airflow-providers-common-compat <https://airflow.apache.org/docs/apache-airflow-providers-common-compat>`_ ``common.compat``
129
- `apache-airflow-providers-common-sql <https://airflow.apache.org/docs/apache-airflow-providers-common-sql>`_ ``common.sql``
130
- `apache-airflow-providers-openlineage <https://airflow.apache.org/docs/apache-airflow-providers-openlineage>`_ ``openlineage``
131
- ================================================================================================================== =================
127
+ ====================================================================================================================== ===================
128
+ Dependent package Extra
129
+ ====================================================================================================================== ===================
130
+ `apache-airflow-providers-common-compat <https://airflow.apache.org/docs/apache-airflow-providers-common-compat>`_ ``common.compat``
131
+ `apache-airflow-providers-common-sql <https://airflow.apache.org/docs/apache-airflow-providers-common-sql>`_ ``common.sql``
132
+ `apache-airflow-providers-microsoft-azure <https://airflow.apache.org/docs/apache-airflow-providers-microsoft-azure>`_ ``microsoft.azure``
133
+ `apache-airflow-providers-openlineage <https://airflow.apache.org/docs/apache-airflow-providers-openlineage>`_ ``openlineage``
134
+ ====================================================================================================================== ===================
132
135
 
133
136
  Optional dependencies
134
137
  ----------------------
135
138
 
136
- =============== ===============================================
137
- Extra Dependencies
138
- =============== ===============================================
139
- ``openlineage`` ``apache-airflow-providers-openlineage>=2.3.0``
140
- =============== ===============================================
139
+ =================== ===============================================
140
+ Extra Dependencies
141
+ =================== ===============================================
142
+ ``microsoft.azure`` ``apache-airflow-providers-microsoft-azure``
143
+ ``openlineage`` ``apache-airflow-providers-openlineage>=2.3.0``
144
+ =================== ===============================================
141
145
 
142
146
  The changelog for the provider package can be found in the
143
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.5.4/changelog.html>`_.
147
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.6.0/changelog.html>`_.
144
148
 
@@ -1,17 +1,17 @@
1
1
  airflow/providers/snowflake/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
2
- airflow/providers/snowflake/__init__.py,sha256=1IYBwYxNexso8poXjRGjeSaUUzT3ir8hIfKr0tHkaVE,1498
3
- airflow/providers/snowflake/get_provider_info.py,sha256=NdNRMfulBbpD-I4yFRr8U533m9djD18ijEMvuxOp4_g,3875
4
- airflow/providers/snowflake/version_compat.py,sha256=7RHBehpYMeNSBtmJiPUeJHA0c7l-Eqsdy546kW3RFa4,1712
2
+ airflow/providers/snowflake/__init__.py,sha256=ZaCbaYhiGxsrneNj5oAl0VzXE0pylEOVgPwrgzTXV90,1498
3
+ airflow/providers/snowflake/get_provider_info.py,sha256=UnvI6oVcI5LN6MAV21dUCGxU_TxHsAjctSIcFgMhLOg,4711
4
+ airflow/providers/snowflake/version_compat.py,sha256=RQbdCueLOaFZWekpQmF0BoAoJInW8EoyvJ3Ah-HbrPo,1577
5
5
  airflow/providers/snowflake/decorators/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
6
- airflow/providers/snowflake/decorators/snowpark.py,sha256=5ocPY8wrXvKbZJokefV4HDfX0WXzrHmcekXoZjkfHEw,5523
6
+ airflow/providers/snowflake/decorators/snowpark.py,sha256=Bxge_oCz_iGqgUeMlaY3GW741PAIwnLIeQO_OXBCwYY,5219
7
7
  airflow/providers/snowflake/hooks/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
8
- airflow/providers/snowflake/hooks/snowflake.py,sha256=PhypqxeK6HZBlAKKkghRjIqCKFRkaWrkgA9yfcBB26I,28356
8
+ airflow/providers/snowflake/hooks/snowflake.py,sha256=4kFJArEM_cd59CslxanhCO9J3KYKBTfFKWLAJrLpDBY,30393
9
9
  airflow/providers/snowflake/hooks/snowflake_sql_api.py,sha256=zILRl-O2y2c8GUA4RHvZOxBkeoGuhD1I9pIQ7thOwAQ,22922
10
10
  airflow/providers/snowflake/operators/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
11
- airflow/providers/snowflake/operators/snowflake.py,sha256=fFsGKk0bGKE6uR6nn3QcBHxlI_B3zt0AiD8Tuw5gGAw,22940
11
+ airflow/providers/snowflake/operators/snowflake.py,sha256=CPvH3tj2A-L9mI7PPppjc_Z9Sw0YKsXwyFhf6LGci10,22792
12
12
  airflow/providers/snowflake/operators/snowpark.py,sha256=Tfd31My6arGXKo0yfi46HyVfkHO3yeT085l3ymxtGpk,5815
13
13
  airflow/providers/snowflake/transfers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
14
- airflow/providers/snowflake/transfers/copy_into_snowflake.py,sha256=2WQDhD9U1l38ZoIv7FImsV6S3gT_rSisg_isNi4k08E,13618
14
+ airflow/providers/snowflake/transfers/copy_into_snowflake.py,sha256=O1kV1_FoXUBxdX0UNlxJVqgcgutoHS6DI-Ipx9iDfvg,13611
15
15
  airflow/providers/snowflake/triggers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
16
16
  airflow/providers/snowflake/triggers/snowflake_trigger.py,sha256=QXNLijmtZI7NIdPtOwbvS-4ohgrm8RV_jaBKvekosHQ,4051
17
17
  airflow/providers/snowflake/utils/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
@@ -19,7 +19,7 @@ airflow/providers/snowflake/utils/common.py,sha256=DG-KLy2KpZWAqZqm_XIECm8lmdoUl
19
19
  airflow/providers/snowflake/utils/openlineage.py,sha256=JdGHyiNBhd7qsNw4OROF5sW3PlFLH_JrSBReGhuxmkk,19396
20
20
  airflow/providers/snowflake/utils/snowpark.py,sha256=-S6ltYiW-KooqUMGzY0OebmAzpUAu7GIjFWwuYERuk8,1629
21
21
  airflow/providers/snowflake/utils/sql_api_generate_jwt.py,sha256=9mR-vHIquv60tfAni87f6FAjKsiRHUDDrsVhzw4M9vM,6762
22
- apache_airflow_providers_snowflake-6.5.4rc1.dist-info/entry_points.txt,sha256=bCrl5J1PXUMzbgnrKYho61rkbL2gHRT4I6f_1jlxAX4,105
23
- apache_airflow_providers_snowflake-6.5.4rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
24
- apache_airflow_providers_snowflake-6.5.4rc1.dist-info/METADATA,sha256=9rp6WonNzAr7Qy8d583feF6WOkh8NoxnDOZMKHt-EO8,7271
25
- apache_airflow_providers_snowflake-6.5.4rc1.dist-info/RECORD,,
22
+ apache_airflow_providers_snowflake-6.6.0.dist-info/entry_points.txt,sha256=bCrl5J1PXUMzbgnrKYho61rkbL2gHRT4I6f_1jlxAX4,105
23
+ apache_airflow_providers_snowflake-6.6.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
24
+ apache_airflow_providers_snowflake-6.6.0.dist-info/METADATA,sha256=G_jPlzNWiFc_X6O7F0HWxp-XNzP-aa2o9UlSRDt_QfM,7631
25
+ apache_airflow_providers_snowflake-6.6.0.dist-info/RECORD,,