Skip to content

Commit 1220e60

Browse files
authored
Add support for Snowflake authenticator (#644)
* add support for snowflake authenticator * dbt only load default connection
1 parent 9ab1d8c commit 1220e60

3 files changed

Lines changed: 43 additions & 6 deletions

File tree

sqlmesh/core/config/connection.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import sys
55
import typing as t
66

7-
from pydantic import Field
7+
from pydantic import Field, root_validator
88

99
from sqlmesh.core import engine_adapter
1010
from sqlmesh.core.config.base import BaseConfig
@@ -13,6 +13,7 @@
1313
http_headers_validator,
1414
)
1515
from sqlmesh.core.engine_adapter import EngineAdapter
16+
from sqlmesh.utils.errors import ConfigError
1617

1718
if sys.version_info >= (3, 9):
1819
from typing import Annotated, Literal
@@ -89,31 +90,45 @@ class SnowflakeConnectionConfig(_ConnectionConfig):
8990
"""Configuration for the Snowflake connection.
9091
9192
Args:
93+
account: The Snowflake account name.
9294
user: The Snowflake username.
9395
password: The Snowflake password.
94-
account: The Snowflake account name.
9596
warehouse: The optional warehouse name.
9697
database: The optional database name.
9798
role: The optional role name.
9899
concurrent_tasks: The maximum number of tasks that can use this connection concurrently.
100+
authenticator: The optional authenticator name. Defaults to username/password authentication ("snowflake").
101+
Options: https://github.com/snowflakedb/snowflake-connector-python/blob/e937591356c067a77f34a0a42328907fda792c23/src/snowflake/connector/network.py#L178-L183
99102
"""
100103

101-
user: str
102-
password: str
103104
account: str
105+
user: t.Optional[str]
106+
password: t.Optional[str]
104107
warehouse: t.Optional[str]
105108
database: t.Optional[str]
106109
role: t.Optional[str]
110+
authenticator: t.Optional[str]
107111

108112
concurrent_tasks: int = 4
109113

110114
type_: Literal["snowflake"] = Field(alias="type", default="snowflake")
111115

112116
_concurrent_tasks_validator = concurrent_tasks_validator
113117

118+
@root_validator()
119+
def _validate_authenticator(
120+
cls, fields: t.Dict[str, t.Optional[str]]
121+
) -> t.Dict[str, t.Optional[str]]:
122+
auth = fields.get("authenticator")
123+
user = fields.get("user")
124+
password = fields.get("password")
125+
if not auth and (not user or not password):
126+
raise ConfigError("User and password must be provided if using default authentication")
127+
return fields
128+
114129
@property
115130
def _connection_kwargs_keys(self) -> t.Set[str]:
116-
return {"user", "password", "account", "warehouse", "database", "role"}
131+
return {"user", "password", "account", "warehouse", "database", "role", "authenticator"}
117132

118133
@property
119134
def _engine_adapter(self) -> t.Type[EngineAdapter]:

sqlmesh/dbt/profile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,4 @@ def _read_profile(
101101
return (targets, default_target)
102102

103103
def to_sqlmesh(self) -> t.Dict[str, ConnectionConfig]:
104-
return {name: target.to_sqlmesh() for name, target in self.targets.items()}
104+
return {self.default_target: self.targets[self.default_target].to_sqlmesh()}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import pytest
2+
3+
from sqlmesh.core.config.connection import SnowflakeConnectionConfig
4+
from sqlmesh.utils.errors import ConfigError
5+
6+
7+
def test_snowflake_auth():
8+
# Authenticator and user/password is fine
9+
SnowflakeConnectionConfig(
10+
account="test", user="test", password="test", authenticator="externalbrowser"
11+
)
12+
# Auth with no user/password is fine
13+
SnowflakeConnectionConfig(account="test", authenticator="externalbrowser")
14+
# No auth and no user raises
15+
with pytest.raises(ConfigError):
16+
SnowflakeConnectionConfig(account="test", password="test")
17+
# No auth and no password raises
18+
with pytest.raises(ConfigError):
19+
SnowflakeConnectionConfig(account="test", user="test")
20+
# No auth and no user/password raises
21+
with pytest.raises(ConfigError):
22+
SnowflakeConnectionConfig(account="test")

0 commit comments

Comments
 (0)