firn 0.15.0

snowflake-rs fork: cancellation, async, streaming, multi-statement, bind params, structured types, retry middleware
Documentation
# firn

Rust client for Snowflake's internal HTTP API (the same endpoint the
official drivers use). Forked from
[`snowflake-api`](https://crates.io/crates/snowflake-api) at v0.14.0
([andrusha/snowflake-rs](https://github.com/andrusha/snowflake-rs)).

```toml
[dependencies]
firn = "0.15"
```

Default features: `cert-auth`. Optional: `browser-auth`, `polars`.

## Quick start

```rust
use firn::{QueryData, SnowflakeApi};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let api = SnowflakeApi::from_env()?;
    let r = api.exec("SELECT current_version()").await?;
    match r.data {
        QueryData::Arrow(batches) => { /* ... */ }
        QueryData::Json(v) => { /* ... */ }
        QueryData::Empty => {}
    }
    Ok(())
}
```

## Features

### Auth
- password ([`with_password_auth`])
- key-pair JWT ([`with_certificate_auth`], `cert-auth` feature, default)
- external-browser SSO ([`with_browser_auth`], `browser-auth` feature)
- env-driven ([`from_env`])

### Queries
- single statement ([`run_sql.rs`]./examples/run_sql.rs)
- positional `?` bind parameters ([`run_sql_bound.rs`]./examples/run_sql_bound.rs)
- multi-statement (`execute_multi`, `execute_multi_exact`) ([`multi_statement.rs`]./examples/multi_statement.rs)
- per-request session-parameter overrides (`with_session_param`) ([`session_params.rs`]./examples/session_params.rs)
- async long-running queries with transparent polling ([`run_sql_long_running.rs`]./examples/run_sql_long_running.rs)
- submit + fetch-by-`query_id` across processes (`submit_async`, `query_status`, `fetch_results`) ([`query_by_id.rs`]./examples/query_by_id.rs)
- describe-only introspection (`describe()`) ([`describe_query.rs`]./examples/describe_query.rs)

### Results
- Arrow `RecordBatch`, with streaming and raw-IPC variants ([`streaming.rs`]./examples/streaming.rs)
- JSON results when the session is configured for JSON
- per-query `QueryMetadata`: `query_id`, `total_rows`, `total_chunks`, `statement_type_id`, executing warehouse/database/schema/role
- `cast_structured()` rewrites `MAP` / `OBJECT` / `ARRAY` columns from JSON-in-Utf8 into native Arrow `Map<Utf8, V>` / `List<E>` ([`compound_types.rs`]./examples/compound_types.rs)
- `GEOGRAPHY` / `GEOMETRY` carried via `FieldSchema::ext_type_name`; `VECTOR` via `vector_dimension` + element type
- `StatementType` enum, `is_dql()` predicate

### Cancellation
- token-based via `CancellationToken` ([`cancel_query.rs`]./examples/cancel_query.rs)
- cross-task by `request_id` (`cancel_query`) ([`cancel_by_id.rs`]./examples/cancel_by_id.rs)
- cross-process by `query_id` (`cancel_query_by_id`) ([`cancel_by_query_id.rs`]./examples/cancel_by_query_id.rs)

### Session
- session-keep-alive heartbeat (`with_keep_alive`) ([`keep_alive.rs`]./examples/keep_alive.rs)
- session-token renewal on `390112` mid-flight
- parallel queries on a shared `SnowflakeApi` with a lock-free hot path (`arc-swap`) ([`parallel_queries.rs`]./examples/parallel_queries.rs)

### Connection
- retry middleware that rotates `request_guid` per attempt and writes `retryCount` / `retryReason` / `clientStartTime` on retried `query-request` calls
- configurable connect and request timeouts
- credentials and auth tokens wrapped in [`SecretString`]https://docs.rs/secrecy/ (`Debug`-redacted, zeroized on drop)
- custom reqwest middleware injection ([`tracing/`]./examples/tracing/)

### PUT
- AWS S3 storage backend
- glob expansion (`PUT 'file:///tmp/*.csv' @stage`)
- parallel upload of small files

### Integrations
- polars `DataFrame` conversion (`polars` feature) ([`polars/`]./examples/polars/)

## Why

Snowflake exposes two HTTP APIs: the public [SQL REST API](https://docs.snowflake.com/developer-guide/sql-api/intro)
and the undocumented endpoint that the official drivers use. This crate
targets the latter, since it supports Arrow output and `PUT`/`GET`.

The wire format and retry/cancel semantics follow
[gosnowflake](https://github.com/snowflakedb/gosnowflake), the Go
driver, since it outputs Arrow by default and is the most legible
reference implementation.

## License

Apache-2.0. Original work © Andrew Korzhuev (andrusha/snowflake-rs);
fork modifications © Will Eaton. See [`LICENSE`](../LICENSE).

[`with_password_auth`]: https://docs.rs/firn/latest/firn/struct.SnowflakeApi.html#method.with_password_auth
[`with_certificate_auth`]: https://docs.rs/firn/latest/firn/struct.SnowflakeApi.html#method.with_certificate_auth
[`with_browser_auth`]: https://docs.rs/firn/latest/firn/struct.SnowflakeApi.html#method.with_browser_auth
[`from_env`]: https://docs.rs/firn/latest/firn/struct.SnowflakeApi.html#method.from_env