apache-airflow-providers-snowflake 6.8.1rc1__py3-none-any.whl → 6.8.2__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.
- airflow/providers/snowflake/__init__.py +1 -1
- airflow/providers/snowflake/hooks/snowflake.py +141 -61
- airflow/providers/snowflake/hooks/snowflake_sql_api.py +2 -2
- airflow/providers/snowflake/operators/snowflake.py +1 -2
- {apache_airflow_providers_snowflake-6.8.1rc1.dist-info → apache_airflow_providers_snowflake-6.8.2.dist-info}/METADATA +11 -11
- {apache_airflow_providers_snowflake-6.8.1rc1.dist-info → apache_airflow_providers_snowflake-6.8.2.dist-info}/RECORD +10 -10
- {apache_airflow_providers_snowflake-6.8.1rc1.dist-info → apache_airflow_providers_snowflake-6.8.2.dist-info}/licenses/NOTICE +1 -1
- {apache_airflow_providers_snowflake-6.8.1rc1.dist-info → apache_airflow_providers_snowflake-6.8.2.dist-info}/WHEEL +0 -0
- {apache_airflow_providers_snowflake-6.8.1rc1.dist-info → apache_airflow_providers_snowflake-6.8.2.dist-info}/entry_points.txt +0 -0
- {apache_airflow_providers_snowflake-6.8.1rc1.dist-info → apache_airflow_providers_snowflake-6.8.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
|
|
|
29
29
|
|
|
30
30
|
__all__ = ["__version__"]
|
|
31
31
|
|
|
32
|
-
__version__ = "6.8.
|
|
32
|
+
__version__ = "6.8.2"
|
|
33
33
|
|
|
34
34
|
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
|
|
35
35
|
"2.11.0"
|
|
@@ -21,6 +21,7 @@ import base64
|
|
|
21
21
|
import os
|
|
22
22
|
from collections.abc import Callable, Iterable, Mapping
|
|
23
23
|
from contextlib import closing, contextmanager
|
|
24
|
+
from datetime import datetime, timedelta
|
|
24
25
|
from functools import cached_property
|
|
25
26
|
from io import StringIO
|
|
26
27
|
from pathlib import Path
|
|
@@ -36,15 +37,23 @@ from snowflake.connector import DictCursor, SnowflakeConnection, util_text
|
|
|
36
37
|
from snowflake.sqlalchemy import URL
|
|
37
38
|
from sqlalchemy import create_engine
|
|
38
39
|
|
|
39
|
-
from airflow.
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
from airflow.providers.common.compat.sdk import (
|
|
41
|
+
AirflowException,
|
|
42
|
+
AirflowOptionalProviderFeatureException,
|
|
43
|
+
Connection,
|
|
44
|
+
conf,
|
|
45
|
+
)
|
|
42
46
|
from airflow.providers.common.sql.hooks.handlers import return_single_query_results
|
|
43
47
|
from airflow.providers.common.sql.hooks.sql import DbApiHook
|
|
44
48
|
from airflow.providers.snowflake.utils.openlineage import fix_snowflake_sqlalchemy_uri
|
|
49
|
+
from airflow.utils import timezone
|
|
45
50
|
from airflow.utils.strings import to_boolean
|
|
46
51
|
|
|
52
|
+
OAUTH_REQUEST_TIMEOUT = 30 # seconds, avoid hanging tasks on token request
|
|
53
|
+
OAUTH_EXPIRY_BUFFER = 30
|
|
47
54
|
T = TypeVar("T")
|
|
55
|
+
|
|
56
|
+
|
|
48
57
|
if TYPE_CHECKING:
|
|
49
58
|
from airflow.providers.openlineage.extractors import OperatorLineage
|
|
50
59
|
from airflow.providers.openlineage.sqlparser import DatabaseInfo
|
|
@@ -174,6 +183,11 @@ class SnowflakeHook(DbApiHook):
|
|
|
174
183
|
self.client_store_temporary_credential = kwargs.pop("client_store_temporary_credential", None)
|
|
175
184
|
self.query_ids: list[str] = []
|
|
176
185
|
|
|
186
|
+
# Access token and expiration timestamp persisted
|
|
187
|
+
# to handle premature expiry.
|
|
188
|
+
self._oauth_token: str | None = None
|
|
189
|
+
self._oauth_token_expires_at: datetime | None = None
|
|
190
|
+
|
|
177
191
|
def _get_field(self, extra_dict, field_name):
|
|
178
192
|
backcompat_prefix = "extra__snowflake__"
|
|
179
193
|
backcompat_key = f"{backcompat_prefix}{field_name}"
|
|
@@ -199,7 +213,7 @@ class SnowflakeHook(DbApiHook):
|
|
|
199
213
|
@property
|
|
200
214
|
def account_identifier(self) -> str:
|
|
201
215
|
"""Get snowflake account identifier."""
|
|
202
|
-
conn_config = self._get_conn_params
|
|
216
|
+
conn_config = self._get_conn_params()
|
|
203
217
|
account_identifier = f"https://{conn_config['account']}"
|
|
204
218
|
|
|
205
219
|
if conn_config["region"]:
|
|
@@ -215,46 +229,15 @@ class SnowflakeHook(DbApiHook):
|
|
|
215
229
|
) -> str:
|
|
216
230
|
"""Generate temporary OAuth access token using refresh token in connection details."""
|
|
217
231
|
if conn_config is None:
|
|
218
|
-
conn_config = self.
|
|
232
|
+
conn_config = self._get_static_conn_params
|
|
219
233
|
|
|
220
|
-
|
|
234
|
+
if token_endpoint is None:
|
|
235
|
+
token_endpoint = conn_config.get("token_endpoint")
|
|
221
236
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
"redirect_uri": conn_config.get("redirect_uri", "https://localhost.com"),
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
scope = conn_config.get("scope")
|
|
228
|
-
|
|
229
|
-
if scope:
|
|
230
|
-
data["scope"] = scope
|
|
231
|
-
|
|
232
|
-
if grant_type == "refresh_token":
|
|
233
|
-
data |= {
|
|
234
|
-
"refresh_token": conn_config["refresh_token"],
|
|
235
|
-
}
|
|
236
|
-
elif grant_type == "client_credentials":
|
|
237
|
-
pass # no setup necessary for client credentials grant.
|
|
238
|
-
else:
|
|
239
|
-
raise ValueError(f"Unknown grant_type: {grant_type}")
|
|
240
|
-
|
|
241
|
-
response = requests.post(
|
|
242
|
-
url,
|
|
243
|
-
data=data,
|
|
244
|
-
headers={
|
|
245
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
246
|
-
},
|
|
247
|
-
auth=HTTPBasicAuth(conn_config["client_id"], conn_config["client_secret"]), # type: ignore[arg-type]
|
|
237
|
+
return self._get_valid_oauth_token(
|
|
238
|
+
conn_config=conn_config, token_endpoint=token_endpoint, grant_type=grant_type
|
|
248
239
|
)
|
|
249
240
|
|
|
250
|
-
try:
|
|
251
|
-
response.raise_for_status()
|
|
252
|
-
except requests.exceptions.HTTPError as e: # pragma: no cover
|
|
253
|
-
msg = f"Response: {e.response.content.decode()} Status Code: {e.response.status_code}"
|
|
254
|
-
raise AirflowException(msg)
|
|
255
|
-
token = response.json()["access_token"]
|
|
256
|
-
return token
|
|
257
|
-
|
|
258
241
|
def get_azure_oauth_token(self, azure_conn_id: str) -> str:
|
|
259
242
|
"""
|
|
260
243
|
Generate OAuth access token using Azure connection id.
|
|
@@ -287,12 +270,42 @@ class SnowflakeHook(DbApiHook):
|
|
|
287
270
|
token = azure_base_hook.get_token(scope).token
|
|
288
271
|
return token
|
|
289
272
|
|
|
290
|
-
@cached_property
|
|
291
273
|
def _get_conn_params(self) -> dict[str, str | None]:
|
|
292
274
|
"""
|
|
293
275
|
Fetch connection params as a dict.
|
|
294
276
|
|
|
295
|
-
This is used in ``get_uri()`` and ``
|
|
277
|
+
This is used in ``get_uri()`` and ``get_conn()``.
|
|
278
|
+
"""
|
|
279
|
+
static_config = self._get_static_conn_params
|
|
280
|
+
conn_config = dict(static_config)
|
|
281
|
+
|
|
282
|
+
if conn_config.get("authenticator") == "oauth":
|
|
283
|
+
azure_conn_id = conn_config.get("azure_conn_id")
|
|
284
|
+
if azure_conn_id:
|
|
285
|
+
conn_config["token"] = self.get_azure_oauth_token(azure_conn_id)
|
|
286
|
+
else:
|
|
287
|
+
grant_type = conn_config.get("grant_type")
|
|
288
|
+
if not grant_type:
|
|
289
|
+
raise ValueError("Grant_type not provided")
|
|
290
|
+
conn_config["token"] = self._get_valid_oauth_token(
|
|
291
|
+
conn_config=conn_config,
|
|
292
|
+
token_endpoint=conn_config.get("token_endpoint"),
|
|
293
|
+
grant_type=grant_type,
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
conn_config.pop("login", None)
|
|
297
|
+
conn_config.pop("user", None)
|
|
298
|
+
conn_config.pop("password", None)
|
|
299
|
+
return conn_config
|
|
300
|
+
|
|
301
|
+
@cached_property
|
|
302
|
+
def _get_static_conn_params(self) -> dict[str, str | None]:
|
|
303
|
+
"""
|
|
304
|
+
Return static Snowflake connection parameters.
|
|
305
|
+
|
|
306
|
+
These parameters are cached for the lifetime of the hook and exclude
|
|
307
|
+
time-sensitive values such as OAuth access tokens. This is used in
|
|
308
|
+
``_get_valid_oauth_token()`` and ``get_conn_params()``.
|
|
296
309
|
"""
|
|
297
310
|
conn = self.get_connection(self.get_conn_id())
|
|
298
311
|
extra_dict = conn.extra_dejson
|
|
@@ -389,25 +402,21 @@ class SnowflakeHook(DbApiHook):
|
|
|
389
402
|
conn_config["refresh_token"] = refresh_token
|
|
390
403
|
conn_config["authenticator"] = "oauth"
|
|
391
404
|
|
|
405
|
+
grant_type = self._get_field(extra_dict, "grant_type") or ""
|
|
406
|
+
if grant_type:
|
|
407
|
+
conn_config["grant_type"] = grant_type
|
|
408
|
+
elif refresh_token:
|
|
409
|
+
conn_config["grant_type"] = "refresh_token"
|
|
410
|
+
|
|
392
411
|
if conn_config.get("authenticator") == "oauth":
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
token_endpoint = self._get_field(extra_dict, "token_endpoint") or ""
|
|
412
|
+
conn_config["azure_conn_id"] = extra_dict.get("azure_conn_id")
|
|
413
|
+
|
|
414
|
+
if not extra_dict.get("azure_conn_id"):
|
|
415
|
+
conn_config["token_endpoint"] = self._get_field(extra_dict, "token_endpoint") or ""
|
|
397
416
|
conn_config["scope"] = self._get_field(extra_dict, "scope")
|
|
398
417
|
conn_config["client_id"] = conn.login
|
|
399
418
|
conn_config["client_secret"] = conn.password
|
|
400
419
|
|
|
401
|
-
conn_config["token"] = self.get_oauth_token(
|
|
402
|
-
conn_config=conn_config,
|
|
403
|
-
token_endpoint=token_endpoint,
|
|
404
|
-
grant_type=extra_dict.get("grant_type", "refresh_token"),
|
|
405
|
-
)
|
|
406
|
-
|
|
407
|
-
conn_config.pop("login", None)
|
|
408
|
-
conn_config.pop("user", None)
|
|
409
|
-
conn_config.pop("password", None)
|
|
410
|
-
|
|
411
420
|
# configure custom target hostname and port, if specified
|
|
412
421
|
snowflake_host = extra_dict.get("host")
|
|
413
422
|
snowflake_port = extra_dict.get("port")
|
|
@@ -424,9 +433,80 @@ class SnowflakeHook(DbApiHook):
|
|
|
424
433
|
|
|
425
434
|
return conn_config
|
|
426
435
|
|
|
436
|
+
def _get_valid_oauth_token(
|
|
437
|
+
self,
|
|
438
|
+
*,
|
|
439
|
+
conn_config: dict[str, Any],
|
|
440
|
+
token_endpoint: str | None,
|
|
441
|
+
grant_type: str,
|
|
442
|
+
) -> str:
|
|
443
|
+
"""
|
|
444
|
+
Return a valid OAuth access token.
|
|
445
|
+
|
|
446
|
+
This also updates the internal OAuth token cache and token expiry timestamp.
|
|
447
|
+
"""
|
|
448
|
+
# Check validity using current timestamp.
|
|
449
|
+
now = timezone.utcnow()
|
|
450
|
+
|
|
451
|
+
if (
|
|
452
|
+
self._oauth_token is not None
|
|
453
|
+
and self._oauth_token_expires_at is not None
|
|
454
|
+
and now < self._oauth_token_expires_at
|
|
455
|
+
):
|
|
456
|
+
return self._oauth_token
|
|
457
|
+
|
|
458
|
+
url = token_endpoint or f"https://{conn_config['account']}.snowflakecomputing.com/oauth/token-request"
|
|
459
|
+
|
|
460
|
+
data = {
|
|
461
|
+
"grant_type": grant_type,
|
|
462
|
+
"redirect_uri": conn_config.get("redirect_uri", "https://localhost.com"),
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
scope = conn_config.get("scope")
|
|
466
|
+
|
|
467
|
+
if scope:
|
|
468
|
+
data["scope"] = scope
|
|
469
|
+
|
|
470
|
+
if grant_type == "refresh_token":
|
|
471
|
+
data |= {
|
|
472
|
+
"refresh_token": conn_config["refresh_token"],
|
|
473
|
+
}
|
|
474
|
+
elif grant_type == "client_credentials":
|
|
475
|
+
pass # no setup necessary for client credentials grant.
|
|
476
|
+
else:
|
|
477
|
+
raise ValueError(f"Unknown grant_type: {grant_type}")
|
|
478
|
+
|
|
479
|
+
response = requests.post(
|
|
480
|
+
url,
|
|
481
|
+
data=data,
|
|
482
|
+
headers={
|
|
483
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
484
|
+
},
|
|
485
|
+
auth=HTTPBasicAuth(conn_config["client_id"], conn_config["client_secret"]), # type: ignore[arg-type]
|
|
486
|
+
timeout=OAUTH_REQUEST_TIMEOUT,
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
try:
|
|
490
|
+
response.raise_for_status()
|
|
491
|
+
except requests.exceptions.HTTPError as e: # pragma: no cover
|
|
492
|
+
msg = f"Response: {e.response.content.decode()} Status Code: {e.response.status_code}"
|
|
493
|
+
raise AirflowException(msg)
|
|
494
|
+
|
|
495
|
+
token = response.json()["access_token"]
|
|
496
|
+
expires_in = int(response.json()["expires_in"])
|
|
497
|
+
|
|
498
|
+
# Capture issue timestamp after access token is retrieved.
|
|
499
|
+
issued_at = timezone.utcnow()
|
|
500
|
+
|
|
501
|
+
# Persist retrieved access token and expiration timestamp.
|
|
502
|
+
self._oauth_token = token
|
|
503
|
+
self._oauth_token_expires_at = issued_at + timedelta(seconds=max(expires_in - OAUTH_EXPIRY_BUFFER, 0))
|
|
504
|
+
|
|
505
|
+
return token
|
|
506
|
+
|
|
427
507
|
def get_uri(self) -> str:
|
|
428
508
|
"""Override DbApiHook get_uri method for get_sqlalchemy_engine()."""
|
|
429
|
-
conn_params = self._get_conn_params
|
|
509
|
+
conn_params = self._get_conn_params()
|
|
430
510
|
return self._conn_params_to_sqlalchemy_uri(conn_params)
|
|
431
511
|
|
|
432
512
|
def _conn_params_to_sqlalchemy_uri(self, conn_params: dict) -> str:
|
|
@@ -450,7 +530,7 @@ class SnowflakeHook(DbApiHook):
|
|
|
450
530
|
|
|
451
531
|
def get_conn(self) -> SnowflakeConnection:
|
|
452
532
|
"""Return a snowflake.connection object."""
|
|
453
|
-
conn_config = self._get_conn_params
|
|
533
|
+
conn_config = self._get_conn_params()
|
|
454
534
|
conn = connector.connect(**conn_config)
|
|
455
535
|
return conn
|
|
456
536
|
|
|
@@ -462,7 +542,7 @@ class SnowflakeHook(DbApiHook):
|
|
|
462
542
|
:return: the created engine.
|
|
463
543
|
"""
|
|
464
544
|
engine_kwargs = engine_kwargs or {}
|
|
465
|
-
conn_params = self._get_conn_params
|
|
545
|
+
conn_params = self._get_conn_params()
|
|
466
546
|
if "insecure_mode" in conn_params:
|
|
467
547
|
engine_kwargs.setdefault("connect_args", {})
|
|
468
548
|
engine_kwargs["connect_args"]["insecure_mode"] = True
|
|
@@ -489,7 +569,7 @@ class SnowflakeHook(DbApiHook):
|
|
|
489
569
|
from airflow import __version__ as airflow_version
|
|
490
570
|
from airflow.providers.snowflake import __version__ as provider_version
|
|
491
571
|
|
|
492
|
-
conn_config = self._get_conn_params
|
|
572
|
+
conn_config = self._get_conn_params()
|
|
493
573
|
session = Session.builder.configs(conn_config).create()
|
|
494
574
|
# add query tag for observability
|
|
495
575
|
session.update_query_tag(
|
|
@@ -655,7 +735,7 @@ class SnowflakeHook(DbApiHook):
|
|
|
655
735
|
return "snowflake"
|
|
656
736
|
|
|
657
737
|
def get_openlineage_default_schema(self) -> str | None:
|
|
658
|
-
return self._get_conn_params["schema"]
|
|
738
|
+
return self._get_conn_params()["schema"]
|
|
659
739
|
|
|
660
740
|
def _get_openlineage_authority(self, _) -> str | None:
|
|
661
741
|
uri = fix_snowflake_sqlalchemy_uri(self.get_uri())
|
|
@@ -163,7 +163,7 @@ class SnowflakeSqlApiHook(SnowflakeHook):
|
|
|
163
163
|
the statement with these specified values.
|
|
164
164
|
"""
|
|
165
165
|
self.query_ids = []
|
|
166
|
-
conn_config = self._get_conn_params
|
|
166
|
+
conn_config = self._get_conn_params()
|
|
167
167
|
|
|
168
168
|
req_id = uuid.uuid4()
|
|
169
169
|
url = f"{self.account_identifier}.snowflakecomputing.com/api/v2/statements"
|
|
@@ -206,7 +206,7 @@ class SnowflakeSqlApiHook(SnowflakeHook):
|
|
|
206
206
|
|
|
207
207
|
def get_headers(self) -> dict[str, Any]:
|
|
208
208
|
"""Form auth headers based on either OAuth token or JWT token from private key."""
|
|
209
|
-
conn_config = self._get_conn_params
|
|
209
|
+
conn_config = self._get_conn_params()
|
|
210
210
|
|
|
211
211
|
# Use OAuth if refresh_token and client_id and client_secret are provided
|
|
212
212
|
if all(
|
|
@@ -23,8 +23,7 @@ from datetime import timedelta
|
|
|
23
23
|
from functools import cached_property
|
|
24
24
|
from typing import TYPE_CHECKING, Any, SupportsAbs, cast
|
|
25
25
|
|
|
26
|
-
from airflow.
|
|
27
|
-
from airflow.providers.common.compat.sdk import AirflowException
|
|
26
|
+
from airflow.providers.common.compat.sdk import AirflowException, conf
|
|
28
27
|
from airflow.providers.common.sql.operators.sql import (
|
|
29
28
|
SQLCheckOperator,
|
|
30
29
|
SQLExecuteQueryOperator,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apache-airflow-providers-snowflake
|
|
3
|
-
Version: 6.8.
|
|
3
|
+
Version: 6.8.2
|
|
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>
|
|
@@ -22,9 +22,9 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
22
22
|
Classifier: Topic :: System :: Monitoring
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
License-File: NOTICE
|
|
25
|
-
Requires-Dist: apache-airflow>=2.11.
|
|
26
|
-
Requires-Dist: apache-airflow-providers-common-compat>=1.
|
|
27
|
-
Requires-Dist: apache-airflow-providers-common-sql>=1.27.
|
|
25
|
+
Requires-Dist: apache-airflow>=2.11.0
|
|
26
|
+
Requires-Dist: apache-airflow-providers-common-compat>=1.12.0
|
|
27
|
+
Requires-Dist: apache-airflow-providers-common-sql>=1.27.5
|
|
28
28
|
Requires-Dist: pandas>=2.1.2; python_version <"3.13"
|
|
29
29
|
Requires-Dist: pandas>=2.2.3; python_version >="3.13"
|
|
30
30
|
Requires-Dist: pyarrow>=16.1.0; python_version < '3.13'
|
|
@@ -34,11 +34,11 @@ Requires-Dist: snowflake-sqlalchemy>=1.7.0
|
|
|
34
34
|
Requires-Dist: snowflake-snowpark-python>=1.17.0,<9999;python_version<'3.12'
|
|
35
35
|
Requires-Dist: snowflake-snowpark-python>=1.27.0,<9999;python_version>='3.12' and python_version<'3.14'
|
|
36
36
|
Requires-Dist: setuptools>=80.0.0,<9999
|
|
37
|
-
Requires-Dist: apache-airflow-providers-microsoft-azure>=12.8.
|
|
38
|
-
Requires-Dist: apache-airflow-providers-openlineage>=2.3.
|
|
37
|
+
Requires-Dist: apache-airflow-providers-microsoft-azure>=12.8.0 ; extra == "microsoft-azure"
|
|
38
|
+
Requires-Dist: apache-airflow-providers-openlineage>=2.3.0 ; extra == "openlineage"
|
|
39
39
|
Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
|
|
40
|
-
Project-URL: Changelog, https://airflow.
|
|
41
|
-
Project-URL: Documentation, https://airflow.
|
|
40
|
+
Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.8.2/changelog.html
|
|
41
|
+
Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.8.2
|
|
42
42
|
Project-URL: Mastodon, https://fosstodon.org/@airflow
|
|
43
43
|
Project-URL: Slack Chat, https://s.apache.org/airflow-slack
|
|
44
44
|
Project-URL: Source Code, https://github.com/apache/airflow
|
|
@@ -71,7 +71,7 @@ Provides-Extra: openlineage
|
|
|
71
71
|
|
|
72
72
|
Package ``apache-airflow-providers-snowflake``
|
|
73
73
|
|
|
74
|
-
Release: ``6.8.
|
|
74
|
+
Release: ``6.8.2``
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
`Snowflake <https://www.snowflake.com/>`__
|
|
@@ -84,7 +84,7 @@ This is a provider package for ``snowflake`` provider. All classes for this prov
|
|
|
84
84
|
are in ``airflow.providers.snowflake`` python package.
|
|
85
85
|
|
|
86
86
|
You can find package information and changelog for the provider
|
|
87
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.8.
|
|
87
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.8.2/>`_.
|
|
88
88
|
|
|
89
89
|
Installation
|
|
90
90
|
------------
|
|
@@ -148,5 +148,5 @@ Extra Dependencies
|
|
|
148
148
|
=================== ====================================================
|
|
149
149
|
|
|
150
150
|
The changelog for the provider package can be found in the
|
|
151
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.8.
|
|
151
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.8.2/changelog.html>`_.
|
|
152
152
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
airflow/providers/snowflake/__init__.py,sha256=
|
|
1
|
+
airflow/providers/snowflake/__init__.py,sha256=UtlBp3Xl6hXKf2c4OS42Xblb0ikc0fpFtho4qZIkTiM,1498
|
|
2
2
|
airflow/providers/snowflake/get_provider_info.py,sha256=UnvI6oVcI5LN6MAV21dUCGxU_TxHsAjctSIcFgMhLOg,4711
|
|
3
3
|
airflow/providers/snowflake/version_compat.py,sha256=RQbdCueLOaFZWekpQmF0BoAoJInW8EoyvJ3Ah-HbrPo,1577
|
|
4
4
|
airflow/providers/snowflake/decorators/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
5
5
|
airflow/providers/snowflake/decorators/snowpark.py,sha256=Bxge_oCz_iGqgUeMlaY3GW741PAIwnLIeQO_OXBCwYY,5219
|
|
6
6
|
airflow/providers/snowflake/hooks/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
7
|
-
airflow/providers/snowflake/hooks/snowflake.py,sha256=
|
|
8
|
-
airflow/providers/snowflake/hooks/snowflake_sql_api.py,sha256=
|
|
7
|
+
airflow/providers/snowflake/hooks/snowflake.py,sha256=uycIPgK3FdLlInFu5VAM-_HX-pobD3JvMlXTud69db8,33352
|
|
8
|
+
airflow/providers/snowflake/hooks/snowflake_sql_api.py,sha256=_yLvsvsEkPMcvKk6lmy7gSBe8SX0PIqZCh1RJoaC8KE,23730
|
|
9
9
|
airflow/providers/snowflake/operators/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
10
|
-
airflow/providers/snowflake/operators/snowflake.py,sha256=
|
|
10
|
+
airflow/providers/snowflake/operators/snowflake.py,sha256=QUPkWm3V_vHzIWx0T4M1O0H_K7b1zNWqCsKsSrA0jaE,23083
|
|
11
11
|
airflow/providers/snowflake/operators/snowpark.py,sha256=Tfd31My6arGXKo0yfi46HyVfkHO3yeT085l3ymxtGpk,5815
|
|
12
12
|
airflow/providers/snowflake/transfers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
|
|
13
13
|
airflow/providers/snowflake/transfers/copy_into_snowflake.py,sha256=O1kV1_FoXUBxdX0UNlxJVqgcgutoHS6DI-Ipx9iDfvg,13611
|
|
@@ -18,9 +18,9 @@ airflow/providers/snowflake/utils/common.py,sha256=DG-KLy2KpZWAqZqm_XIECm8lmdoUl
|
|
|
18
18
|
airflow/providers/snowflake/utils/openlineage.py,sha256=HHMJvTPfCnxO1qMcS6rr9t0N8_jFPdMswEVFY25YoIc,17993
|
|
19
19
|
airflow/providers/snowflake/utils/snowpark.py,sha256=-S6ltYiW-KooqUMGzY0OebmAzpUAu7GIjFWwuYERuk8,1629
|
|
20
20
|
airflow/providers/snowflake/utils/sql_api_generate_jwt.py,sha256=9mR-vHIquv60tfAni87f6FAjKsiRHUDDrsVhzw4M9vM,6762
|
|
21
|
-
apache_airflow_providers_snowflake-6.8.
|
|
22
|
-
apache_airflow_providers_snowflake-6.8.
|
|
23
|
-
apache_airflow_providers_snowflake-6.8.
|
|
24
|
-
apache_airflow_providers_snowflake-6.8.
|
|
25
|
-
apache_airflow_providers_snowflake-6.8.
|
|
26
|
-
apache_airflow_providers_snowflake-6.8.
|
|
21
|
+
apache_airflow_providers_snowflake-6.8.2.dist-info/entry_points.txt,sha256=bCrl5J1PXUMzbgnrKYho61rkbL2gHRT4I6f_1jlxAX4,105
|
|
22
|
+
apache_airflow_providers_snowflake-6.8.2.dist-info/licenses/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
|
|
23
|
+
apache_airflow_providers_snowflake-6.8.2.dist-info/licenses/NOTICE,sha256=_cWHznIoUSbLCY_KfmKqetlKlsoH0c2VBjmZjElAzuc,168
|
|
24
|
+
apache_airflow_providers_snowflake-6.8.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
25
|
+
apache_airflow_providers_snowflake-6.8.2.dist-info/METADATA,sha256=DfS6YcGlzfgOzyY8cRJpFGNRiGUXtlfR8o8XQjs6IKw,7780
|
|
26
|
+
apache_airflow_providers_snowflake-6.8.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|