dagster-snowflake 0.27.1__tar.gz → 0.27.2__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.

Potentially problematic release.


This version of dagster-snowflake might be problematic. Click here for more details.

Files changed (24) hide show
  1. {dagster_snowflake-0.27.1/dagster_snowflake.egg-info → dagster_snowflake-0.27.2}/PKG-INFO +4 -3
  2. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/resources.py +86 -2
  3. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/snowflake_io_manager.py +10 -9
  4. dagster_snowflake-0.27.2/dagster_snowflake/version.py +1 -0
  5. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2/dagster_snowflake.egg-info}/PKG-INFO +4 -3
  6. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake.egg-info/requires.txt +1 -1
  7. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/setup.py +3 -2
  8. dagster_snowflake-0.27.1/dagster_snowflake/version.py +0 -1
  9. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/LICENSE +0 -0
  10. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/MANIFEST.in +0 -0
  11. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/README.md +0 -0
  12. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/__init__.py +0 -0
  13. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/components/__init__.py +0 -0
  14. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/components/sql_component/__init__.py +0 -0
  15. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/components/sql_component/component.py +0 -0
  16. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/constants.py +0 -0
  17. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/ops.py +0 -0
  18. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake/py.typed +0 -0
  19. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake.egg-info/SOURCES.txt +0 -0
  20. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake.egg-info/dependency_links.txt +0 -0
  21. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake.egg-info/entry_points.txt +0 -0
  22. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake.egg-info/not-zip-safe +0 -0
  23. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/dagster_snowflake.egg-info/top_level.txt +0 -0
  24. {dagster_snowflake-0.27.1 → dagster_snowflake-0.27.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster-snowflake
3
- Version: 0.27.1
3
+ Version: 0.27.2
4
4
  Summary: Package for Snowflake Dagster framework components.
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-snowflake
6
6
  Author: Dagster Labs
@@ -10,11 +10,12 @@ Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
13
14
  Classifier: License :: OSI Approved :: Apache Software License
14
15
  Classifier: Operating System :: OS Independent
15
- Requires-Python: >=3.9,<3.13
16
+ Requires-Python: >=3.9,<=3.13.3
16
17
  License-File: LICENSE
17
- Requires-Dist: dagster==1.11.1
18
+ Requires-Dist: dagster==1.11.2
18
19
  Requires-Dist: snowflake-connector-python>=3.4.0
19
20
  Requires-Dist: pyOpenSSL>=22.1.0
20
21
  Provides-Extra: snowflake-sqlalchemy
@@ -281,9 +281,9 @@ class SnowflakeResource(ConfigurableResource, IAttachDifferentObjectToOpContext)
281
281
 
282
282
  @validator("connector")
283
283
  def validate_connector(cls, v: Optional[str]) -> Optional[str]:
284
- if v is not None and v != "sqlalchemy":
284
+ if v is not None and v not in ["sqlalchemy", "adbc"]:
285
285
  raise ValueError(
286
- "Snowflake Resource: 'connector' configuration value must be None or sqlalchemy."
286
+ "Snowflake Resource: 'connector' configuration value must be None, sqlalchemy or adbc."
287
287
  )
288
288
  return v
289
289
 
@@ -391,6 +391,81 @@ class SnowflakeResource(ConfigurableResource, IAttachDifferentObjectToOpContext)
391
391
 
392
392
  return sqlalchemy_engine_args
393
393
 
394
+ @property
395
+ @cached_method
396
+ def _adbc_connection_args(self) -> Mapping[str, Any]:
397
+ config = self._resolved_config_dict
398
+ adbc_engine_args = {}
399
+
400
+ if config.get("account"):
401
+ adbc_engine_args["adbc.snowflake.sql.account"] = config["account"]
402
+ if config.get("user"):
403
+ adbc_engine_args["username"] = config["user"]
404
+ if config.get("password"):
405
+ adbc_engine_args["password"] = config["password"]
406
+ if config.get("database"):
407
+ adbc_engine_args["adbc.snowflake.sql.db"] = config["database"]
408
+ if config.get("schema"):
409
+ adbc_engine_args["adbc.snowflake.sql.schema"] = config["schema"]
410
+ if config.get("role"):
411
+ adbc_engine_args["adbc.snowflake.sql.role"] = config["role"]
412
+ if config.get("warehouse"):
413
+ adbc_engine_args["adbc.snowflake.sql.warehouse"] = config["warehouse"]
414
+
415
+ if config.get("authenticator"):
416
+ auth_mapping = {
417
+ "snowflake": "auth_snowflake",
418
+ "oauth": "auth_oauth",
419
+ "externalbrowser": "auth_ext_browser",
420
+ "okta": "auth_okta",
421
+ "jwt": "auth_jwt",
422
+ "snowflake_jwt": "auth_jwt",
423
+ }
424
+ auth_type = auth_mapping.get(config["authenticator"].lower(), config["authenticator"])
425
+ adbc_engine_args["adbc.snowflake.sql.auth_type"] = auth_type
426
+
427
+ if config.get("private_key") or config.get("private_key_path"):
428
+ # ADBC expects the raw private key value as bytes for jwt_private_key_pkcs8_value
429
+ adbc_engine_args["adbc.snowflake.sql.auth_type"] = "auth_jwt"
430
+ if config.get("private_key"):
431
+ adbc_engine_args["adbc.snowflake.sql.client_option.jwt_private_key_pkcs8_value"] = (
432
+ config["private_key"]
433
+ )
434
+ elif config.get("private_key_path"):
435
+ adbc_engine_args["adbc.snowflake.sql.client_option.jwt_private_key"] = config[
436
+ "private_key_path"
437
+ ]
438
+
439
+ if config.get("private_key_password"):
440
+ adbc_engine_args[
441
+ "adbc.snowflake.sql.client_option.jwt_private_key_pkcs8_password"
442
+ ] = config["private_key_password"]
443
+
444
+ if config.get("login_timeout"):
445
+ adbc_engine_args["adbc.snowflake.sql.client_option.login_timeout"] = (
446
+ f"{config['login_timeout']}s"
447
+ )
448
+ if config.get("network_timeout"):
449
+ adbc_engine_args["adbc.snowflake.sql.client_option.request_timeout"] = (
450
+ f"{config['network_timeout']}s"
451
+ )
452
+ if config.get("client_session_keep_alive") is not None:
453
+ adbc_engine_args["adbc.snowflake.sql.client_option.keep_session_alive"] = str(
454
+ config["client_session_keep_alive"]
455
+ ).lower()
456
+
457
+ adbc_engine_args["adbc.snowflake.sql.client_option.app_name"] = (
458
+ SNOWFLAKE_PARTNER_CONNECTION_IDENTIFIER
459
+ )
460
+
461
+ if config.get("additional_snowflake_connection_args"):
462
+ for key, value in config["additional_snowflake_connection_args"].items():
463
+ # Allow direct ADBC option names to be passed through
464
+ if key.startswith("adbc.snowflake."):
465
+ adbc_engine_args[key] = value # noqa: PERF403
466
+
467
+ return adbc_engine_args
468
+
394
469
  def _snowflake_private_key(self, config) -> bytes:
395
470
  # If the user has defined a path to a private key, we will use that.
396
471
  if config.get("private_key_path", None) is not None:
@@ -476,6 +551,15 @@ class SnowflakeResource(ConfigurableResource, IAttachDifferentObjectToOpContext)
476
551
  yield conn
477
552
  conn.close()
478
553
  engine.dispose()
554
+ elif self.connector == "adbc":
555
+ import adbc_driver_snowflake.dbapi
556
+
557
+ conn = adbc_driver_snowflake.dbapi.connect(
558
+ db_kwargs=self._adbc_connection_args, # pyright: ignore[reportArgumentType]
559
+ )
560
+
561
+ yield conn
562
+ conn.close()
479
563
  else:
480
564
  conn = snowflake.connector.connect(**self._connection_args)
481
565
 
@@ -15,7 +15,6 @@ from dagster._core.storage.db_io_manager import (
15
15
  )
16
16
  from dagster._core.storage.io_manager import dagster_maintained_io_manager
17
17
  from pydantic import Field
18
- from snowflake.connector.errors import ProgrammingError
19
18
 
20
19
  from dagster_snowflake.resources import SnowflakeResource
21
20
 
@@ -364,20 +363,22 @@ class SnowflakeDbClient(DbClient):
364
363
 
365
364
  @staticmethod
366
365
  def ensure_schema_exists(context: OutputContext, table_slice: TableSlice, connection) -> None:
367
- schemas = (
368
- connection.cursor()
369
- .execute(f"show schemas like '{table_slice.schema}' in database {table_slice.database}")
370
- .fetchall()
371
- )
366
+ with connection.cursor() as cursor:
367
+ cursor.execute(
368
+ f"show schemas like '{table_slice.schema}' in database {table_slice.database}"
369
+ )
370
+ schemas = cursor.fetchall()
371
+
372
372
  if len(schemas) == 0:
373
- connection.cursor().execute(f"create schema {table_slice.schema};")
373
+ with connection.cursor() as cursor:
374
+ cursor.execute(f"create schema {table_slice.schema};")
374
375
 
375
376
  @staticmethod
376
377
  def delete_table_slice(context: OutputContext, table_slice: TableSlice, connection) -> None:
377
378
  try:
378
379
  connection.cursor().execute(_get_cleanup_statement(table_slice))
379
- except ProgrammingError as e:
380
- if "does not exist" in e.msg: # type: ignore
380
+ except Exception as e:
381
+ if "does not exist or not authorized" in str(e):
381
382
  # table doesn't exist yet, so ignore the error
382
383
  return
383
384
  else:
@@ -0,0 +1 @@
1
+ __version__ = "0.27.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster-snowflake
3
- Version: 0.27.1
3
+ Version: 0.27.2
4
4
  Summary: Package for Snowflake Dagster framework components.
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-snowflake
6
6
  Author: Dagster Labs
@@ -10,11 +10,12 @@ Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
13
14
  Classifier: License :: OSI Approved :: Apache Software License
14
15
  Classifier: Operating System :: OS Independent
15
- Requires-Python: >=3.9,<3.13
16
+ Requires-Python: >=3.9,<=3.13.3
16
17
  License-File: LICENSE
17
- Requires-Dist: dagster==1.11.1
18
+ Requires-Dist: dagster==1.11.2
18
19
  Requires-Dist: snowflake-connector-python>=3.4.0
19
20
  Requires-Dist: pyOpenSSL>=22.1.0
20
21
  Provides-Extra: snowflake-sqlalchemy
@@ -1,4 +1,4 @@
1
- dagster==1.11.1
1
+ dagster==1.11.2
2
2
  snowflake-connector-python>=3.4.0
3
3
  pyOpenSSL>=22.1.0
4
4
 
@@ -27,14 +27,15 @@ setup(
27
27
  "Programming Language :: Python :: 3.10",
28
28
  "Programming Language :: Python :: 3.11",
29
29
  "Programming Language :: Python :: 3.12",
30
+ "Programming Language :: Python :: 3.13",
30
31
  "License :: OSI Approved :: Apache Software License",
31
32
  "Operating System :: OS Independent",
32
33
  ],
33
34
  packages=find_packages(exclude=["dagster_snowflake_tests*"]),
34
35
  include_package_data=True,
35
- python_requires=">=3.9,<3.13",
36
+ python_requires=">=3.9,<=3.13.3",
36
37
  install_requires=[
37
- "dagster==1.11.1",
38
+ "dagster==1.11.2",
38
39
  "snowflake-connector-python>=3.4.0",
39
40
  # Workaround for incorrect pin in the snowflake-connector-python package
40
41
  # See https://github.com/snowflakedb/snowflake-connector-python/issues/2109
@@ -1 +0,0 @@
1
- __version__ = "0.27.1"