1818 Login name for the Snowflake user.
1919 Alias for `sfUser`.
2020password : SecretStr
21- Password for the Snowflake user.
22- Alias for `sfPassword`.
21+ The password for the snowflake user. Alias for `sfPassword`. Either this or private_key must be provided.
22+ private_key : SecretStr
23+ The private_key for the snowflake user. Either this or password must be provided.
2324database : str
2425 The database to use for the session after connecting.
2526 Alias for `sfDatabase`.
@@ -172,8 +173,9 @@ class SnowflakeBaseModel(BaseModel, ExtraParamsMixin, ABC): # type: ignore[misc
172173 Login name for the Snowflake user.
173174 Alias for `sfUser`.
174175 password : SecretStr
175- Password for the Snowflake user.
176- Alias for `sfPassword`.
176+ The password for the snowflake user. Alias for `sfPassword`. Either this or private_key must be provided.
177+ private_key : SecretStr
178+ The private_key for the snowflake user. Either this or password must be provided.
177179 role : str
178180 The default security role to use for the session after connecting.
179181 Alias for `sfRole`.
@@ -199,7 +201,8 @@ class SnowflakeBaseModel(BaseModel, ExtraParamsMixin, ABC): # type: ignore[misc
199201 examples = ["example.snowflakecomputing.com" ],
200202 )
201203 user : str = Field (default = ..., alias = "sfUser" , description = "Login name for the Snowflake user" )
202- password : SecretStr = Field (default = ..., alias = "sfPassword" , description = "Password for the Snowflake user" )
204+ password : Optional [SecretStr ] = Field (default = None , alias = "sfPassword" , description = "Password for the Snowflake user" )
205+ private_key : Optional [SecretStr ] = Field (default = None , alias = "pem_private_key" , description = "PEM private key for the Snowflake user" )
203206 role : str = Field (
204207 default = ..., alias = "sfRole" , description = "The default security role to use for the session after connecting"
205208 )
@@ -227,6 +230,17 @@ class SnowflakeBaseModel(BaseModel, ExtraParamsMixin, ABC): # type: ignore[misc
227230 examples = [{"sfCompress" : "on" , "continue_on_error" : "off" }],
228231 )
229232
233+ @model_validator (mode = "after" )
234+ def check_authentication_method (self ) -> "SnowflakeBaseModel" :
235+ """Ensure at least one of password or private_key is provided."""
236+ if not self .password and not self .private_key :
237+ raise ValueError ("You must provide either 'password' or 'private_key'." )
238+ if self .password and self .private_key :
239+ raise ValueError (
240+ "You must provide either 'password' or 'private_key', not both."
241+ )
242+ return self
243+
230244 @property
231245 def options (self ) -> Dict [str , Any ]:
232246 """Shorthand for accessing self.params provided for backwards compatibility"""
@@ -260,6 +274,7 @@ def get_options(self, by_alias: bool = True, include: Optional[Set[str]] = None)
260274 # schema and password have to be handled separately
261275 "sfSchema" ,
262276 "password" ,
277+ "private_key" ,
263278 } - (include or set ())
264279
265280 fields = self .model_dump (
@@ -268,13 +283,22 @@ def get_options(self, by_alias: bool = True, include: Optional[Set[str]] = None)
268283 exclude = exclude_set ,
269284 )
270285
286+ fields .update ({ "sfSchema" if by_alias else "schema" : self .sfSchema })
287+
271288 # handle schema and password
272- fields .update (
273- {
274- "sfSchema" if by_alias else "schema" : self .sfSchema ,
275- "sfPassword" if by_alias else "password" : self .password .get_secret_value (),
276- }
277- )
289+ if self .password :
290+ fields .update (
291+ {
292+ "sfPassword" if by_alias else "password" : self .password .get_secret_value (),
293+ }
294+ )
295+ elif self .private_key :
296+ fields .update (
297+ {
298+ "private_key" : self .private_key .get_secret_value (),
299+ "pem_private_key" : self .private_key .get_secret_value (),
300+ }
301+ )
278302
279303 # handle include
280304 if include :
@@ -379,6 +403,7 @@ def get_options(self, by_alias: bool = False, include: Optional[Set[str]] = None
379403 "database" ,
380404 "schema" ,
381405 "password" ,
406+ "private_key" ,
382407 }
383408 return super ().get_options (by_alias = by_alias , include = include )
384409
@@ -389,6 +414,8 @@ def conn(self) -> Generator:
389414 raise RuntimeError ("Snowflake connector is not installed. Please install `snowflake-connector-python`." )
390415
391416 sf_options = self .get_options ()
417+
418+
392419 _conn = self ._snowflake_connector .connect (** sf_options )
393420 self .log .info (f"Connected to Snowflake account: { sf_options ['account' ]} " )
394421
@@ -442,7 +469,9 @@ class GrantPrivilegesOnObject(SnowflakeRunQueryPython):
442469 user : str
443470 The username. Alias for `sfUser`
444471 password : SecretStr
445- The password. Alias for `sfPassword`
472+ The password for the snowflake user. Alias for `sfPassword`. Either this or private_key must be provided.
473+ private_key : SecretStr
474+ The private_key for the snowflake user. Either this or password must be provided.
446475 role : str
447476 The role name
448477 object : str
0 commit comments