A Rust client for Snowflake, which enables you to connect to Snowflake and run queries.
The minimum supported Rust version (MSRV) is 1.88.
#[derive(Debug, PartialEq, snowflake_connector_rs::FromRow)]
struct ExampleRow {
id: i64,
value: String,
}
let session_config = SnowflakeSessionConfig::default()
.with_role("ROLE")
.with_warehouse("WAREHOUSE")
.with_database("DATABASE")
.with_schema("SCHEMA");
let query_config = SnowflakeQueryConfig::default()
.with_async_query_completion_timeout(std::time::Duration::from_secs(30));
let client = SnowflakeClient::new(
SnowflakeClientConfig::new(
"USERNAME",
"ACCOUNT",
SnowflakeAuthConfig::password("PASSWORD"),
)
.with_session(session_config)
.with_query(query_config),
)?;
let session = client.create_session().await?;
session
.query("CREATE TEMPORARY TABLE example (id NUMBER, value STRING)")
.await?;
session
.query("INSERT INTO example (id, value) VALUES (1, 'hello'), (2, 'world')")
.await?;
let dynamic_rows = session
.query("SELECT id, value FROM example ORDER BY id")
.await?
.collect()
.await?;
assert_eq!(dynamic_rows.len(), 2);
let rows: Vec<ExampleRow> = session
.query_as::<ExampleRow, _>("SELECT id, value FROM example ORDER BY id")
.await?
.collect()
.await?;
assert_eq!(
rows,
vec![
ExampleRow {
id: 1,
value: "hello".to_string(),
},
ExampleRow {
id: 2,
value: "world".to_string(),
},
]
);
let typed_table = session
.query_as::<ExampleRow, _>("SELECT id, value FROM example ORDER BY id")
.await?
.collect_table()
.await?;
assert_eq!(typed_table.row_count(), 2);
let mut result = session
.query_as::<ExampleRow, _>("SELECT id, value FROM example ORDER BY id")
.await?;
while let Some(table) = result.next_table().await? {
for row in table.rows() {
let row = row?;
println!("{row:?}");
}
}
let result = session.query("SELECT id, value FROM example ORDER BY id").await?;
let table = result.collect_table().await?;
assert_eq!(table.row_count(), 2);To override the default Snowflake endpoint (e.g. for testing or non-default network setups):
use url::Url;
let auth = SnowflakeAuthConfig::password("PASSWORD");
let endpoint = SnowflakeEndpointConfig::custom_base_url(
Url::parse("https://custom-host.example.com").unwrap(),
);
let client = SnowflakeClient::new(
SnowflakeClientConfig::new("USERNAME", "ACCOUNT", auth)
.with_endpoint(endpoint),
)?;To route requests through an HTTP proxy:
use url::Url;
let auth = SnowflakeAuthConfig::password("PASSWORD");
let proxy = SnowflakeProxyConfig::new(
Url::parse("http://proxy.example.com:8080").unwrap(),
)
.with_basic_auth("proxy_user", "proxy_pass");
let transport = SnowflakeTransportConfig::default().with_proxy(proxy);
let client = SnowflakeClient::new(
SnowflakeClientConfig::new("USERNAME", "ACCOUNT", auth)
.with_transport(transport),
)?;This crate supports optional features to decrypt legacy keys that use DES or 3DES encryption. These algorithms are considered insecure and should only be used for legacy compatibility.
pkcs8-des: Enables DES decryption supportpkcs8-3des: Enables 3DES decryption supportderive: Re-exports theFromRowderive macro (enabled by default)key-pair-auth: Enables key-pair authentication support (enabled by default)external-browser-sso: Enables external browser SSO authentication support
Note
The external-browser-sso feature is experimental.
The implementation and API may change in future releases, and stability or backward compatibility is not guaranteed.
Use this feature with caution in production environments.
Please open an issue for bugs or feature requests.
Typical configurations for the external-browser-sso feature:
- Local default (auto browser launch, localhost callback, auto-picked port)
use snowflake_connector_rs::{ExternalBrowserConfig, SnowflakeAuthConfig}; let auth = SnowflakeAuthConfig::external_browser(ExternalBrowserConfig::default());
- Docker/container setup (manual open with explicit callback bind address/port)
use std::net::Ipv4Addr; use snowflake_connector_rs::{BrowserLaunchMode, ExternalBrowserConfig, SnowflakeAuthConfig}; let external_browser = ExternalBrowserConfig::with_callback_listener( BrowserLaunchMode::Manual, Ipv4Addr::UNSPECIFIED.into(), 3037, ); let auth = SnowflakeAuthConfig::external_browser(external_browser);
- Without callback listener mode (manual redirected URL input)
use std::num::NonZeroU16; use snowflake_connector_rs::{BrowserLaunchMode, ExternalBrowserConfig, SnowflakeAuthConfig}; let redirect_port = NonZeroU16::new(3037).unwrap(); let external_browser = ExternalBrowserConfig::without_callback_listener(BrowserLaunchMode::Manual, redirect_port); let auth = SnowflakeAuthConfig::external_browser(external_browser);
For Docker/container setup, make sure that:
- your Snowflake OAuth redirect URI allows the same callback port (for example
3037), and - the callback port is mapped to the host (for example
-p 3037:3037or equivalent in Compose).
0.0.0.0 binds on all interfaces in the container. Use the minimum required network exposure for your environment.
In WithoutCallbackListener mode:
- no local server is started, so
localhost:<redirect_port>is not actually listened on by this connector. - a non-zero
redirect_portis still required because Snowflake usesBROWSER_MODE_REDIRECT_PORTto construct the browser redirect URL. - the browser may show a connection error page at
localhost:<redirect_port>after login; copy that redirected URL and paste it into the terminal prompt so the connector can extract the token.