apache-airflow-providers-snowflake 6.8.0rc1__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.
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "6.8.0"
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.configuration import conf
40
- from airflow.exceptions import AirflowOptionalProviderFeatureException
41
- from airflow.providers.common.compat.sdk import AirflowException, Connection
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._get_conn_params
232
+ conn_config = self._get_static_conn_params
219
233
 
220
- url = token_endpoint or f"https://{conn_config['account']}.snowflakecomputing.com/oauth/token-request"
234
+ if token_endpoint is None:
235
+ token_endpoint = conn_config.get("token_endpoint")
221
236
 
222
- data = {
223
- "grant_type": grant_type,
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 ``get_connection()``.
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
- if extra_dict.get("azure_conn_id"):
394
- conn_config["token"] = self.get_azure_oauth_token(extra_dict["azure_conn_id"])
395
- else:
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.configuration import conf
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,
@@ -68,15 +68,16 @@ class SnowflakeSqlApiTrigger(BaseTrigger):
68
68
 
69
69
  async def run(self) -> AsyncIterator[TriggerEvent]:
70
70
  """Wait for the query the snowflake query to complete."""
71
- SnowflakeSqlApiHook(
71
+ hook = SnowflakeSqlApiHook(
72
72
  self.snowflake_conn_id,
73
73
  self.token_life_time,
74
74
  self.token_renewal_delta,
75
75
  )
76
+
76
77
  try:
77
78
  for query_id in self.query_ids:
78
79
  while True:
79
- statement_status = await self.get_query_status(query_id)
80
+ statement_status = await self.get_query_status(query_id, hook)
80
81
  if statement_status["status"] not in ["running"]:
81
82
  break
82
83
  await asyncio.sleep(self.poll_interval)
@@ -92,13 +93,17 @@ class SnowflakeSqlApiTrigger(BaseTrigger):
92
93
  except Exception as e:
93
94
  yield TriggerEvent({"status": "error", "message": str(e)})
94
95
 
95
- async def get_query_status(self, query_id: str) -> dict[str, Any]:
96
+ async def get_query_status(
97
+ self, query_id: str, hook: SnowflakeSqlApiHook | None = None
98
+ ) -> dict[str, Any]:
96
99
  """Return True if the SQL query is still running otherwise return False."""
97
- hook = SnowflakeSqlApiHook(
98
- self.snowflake_conn_id,
99
- self.token_life_time,
100
- self.token_renewal_delta,
101
- )
100
+ if not hook:
101
+ hook = SnowflakeSqlApiHook(
102
+ self.snowflake_conn_id,
103
+ self.token_life_time,
104
+ self.token_renewal_delta,
105
+ )
106
+
102
107
  return await hook.get_sql_api_query_status_async(query_id)
103
108
 
104
109
  def _set_context(self, context):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apache-airflow-providers-snowflake
3
- Version: 6.8.0rc1
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.0rc1
26
- Requires-Dist: apache-airflow-providers-common-compat>=1.10.1rc1
27
- Requires-Dist: apache-airflow-providers-common-sql>=1.27.5rc1
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.0rc1 ; extra == "microsoft-azure"
38
- Requires-Dist: apache-airflow-providers-openlineage>=2.3.0rc1 ; extra == "openlineage"
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.staged.apache.org/docs/apache-airflow-providers-snowflake/6.8.0/changelog.html
41
- Project-URL: Documentation, https://airflow.staged.apache.org/docs/apache-airflow-providers-snowflake/6.8.0
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.0``
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.0/>`_.
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.0/changelog.html>`_.
151
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-snowflake/6.8.2/changelog.html>`_.
152
152
 
@@ -1,26 +1,26 @@
1
- airflow/providers/snowflake/__init__.py,sha256=pgddHY3z_6NgaHwG9T-htBh_SJFQSlUfWsNhnrWYOiQ,1498
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=UjUHqVcWctjk0W8gyqdlMmR-TmHWx_nvwOSxW417ufI,30630
8
- airflow/providers/snowflake/hooks/snowflake_sql_api.py,sha256=D6jX_uvpBpzQ_4dXDQcmFROJEfRYj6ehxvEFRN41jQI,23726
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=_ikG_JaU8NN__Jk18sdevEf835hF16Fm87hEmfV3Otw,23116
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
14
14
  airflow/providers/snowflake/triggers/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
15
- airflow/providers/snowflake/triggers/snowflake_trigger.py,sha256=QXNLijmtZI7NIdPtOwbvS-4ohgrm8RV_jaBKvekosHQ,4051
15
+ airflow/providers/snowflake/triggers/snowflake_trigger.py,sha256=U_MuDC6IkxQI7T3MUa3dtVQcdS7OY_LlmTkVnA4l9XM,4162
16
16
  airflow/providers/snowflake/utils/__init__.py,sha256=9hdXHABrVpkbpjZgUft39kOFL2xSGeG4GEua0Hmelus,785
17
17
  airflow/providers/snowflake/utils/common.py,sha256=DG-KLy2KpZWAqZqm_XIECm8lmdoUlzwkXv9onmkQThc,1644
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.0rc1.dist-info/entry_points.txt,sha256=bCrl5J1PXUMzbgnrKYho61rkbL2gHRT4I6f_1jlxAX4,105
22
- apache_airflow_providers_snowflake-6.8.0rc1.dist-info/licenses/LICENSE,sha256=gXPVwptPlW1TJ4HSuG5OMPg-a3h43OGMkZRR1rpwfJA,10850
23
- apache_airflow_providers_snowflake-6.8.0rc1.dist-info/licenses/NOTICE,sha256=E3-_E02gwwSEFzeeWPKmnIjOoos3hW28CLISV6sYrbQ,168
24
- apache_airflow_providers_snowflake-6.8.0rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
25
- apache_airflow_providers_snowflake-6.8.0rc1.dist-info/METADATA,sha256=qQXaINQc2tToeP3m4B3s0b_2f68C6v4ChGX-0Wtvmh8,7812
26
- apache_airflow_providers_snowflake-6.8.0rc1.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Apache Airflow
2
- Copyright 2016-2025 The Apache Software Foundation
2
+ Copyright 2016-2026 The Apache Software Foundation
3
3
 
4
4
  This product includes software developed at
5
5
  The Apache Software Foundation (http://www.apache.org/).