A trino client library written in rust.
This project have been forked on 08/12/24 from the great : prusto made by @nooberfsh.
Fork rationale :
- Remove presto support
- Add advanced trino features.
- Rename things as "trino"
- Basic Auth
- Jwt Auth
- Interactive OAuth2 (browser-based)
- Spooling Protocol (for efficient large result set handling)
# Cargo.toml
[dependencies]
trino-rust-client = "0.11.0"
# For spooling protocol support
trino-rust-client = { version = "0.11.0", features = ["spooling"] }Breaking changes between releases are documented with before/after examples in the migration guide.
The client emits tracing events and wraps each
get_all / stream / execute call in a span carrying the query_id, so
logs correlate per query. Install any subscriber to see them, e.g.:
tracing_subscriber::fmt()
.with_env_filter("trino_rust_client=debug")
.init();use trino_rust_client::{ClientBuilder, Trino};
#[derive(Trino, Debug)]
struct Foo {
a: i64,
b: f64,
c: String,
}
#[tokio::main]
async fn main() {
let cli = ClientBuilder::new("user", "localhost")
.port(8090)
.catalog("catalog")
.build()
.unwrap();
let sql = "select 1 as a, cast(1.1 as double) as b, 'bar' as c ";
let data = cli.get_all::<Foo>(sql.into()).await.unwrap().into_vec();
for r in data {
println!("{:?}", r)
}
}use trino_rust_client::{ClientBuilder, Trino};
#[derive(Trino, Debug)]
struct Foo {
a: i64,
b: f64,
c: String,
}
#[tokio::main]
async fn main() {
let auth = Auth::Jwt("your access token");
let cli = ClientBuilder::new("user", "localhost")
.port(8443)
.secure(true)
.auth(auth)
.catalog("catalog")
.build()
.unwrap();
let sql = "select 1 as a, cast(1.1 as double) as b, 'bar' as c ";
let data = cli.get_all::<Foo>(sql.into()).await.unwrap().into_vec();
for r in data {
println!("{:?}", r)
}
}Trino's OAuth2 authentication makes the coordinator the OAuth client: on a
401 the client opens the coordinator-supplied login URL in a browser (and
prints it to stderr as a fallback), polls Trino's token endpoint until you finish
the IdP login, then retries with the bearer token. The token is cached in the
Auth value: build one Auth and clone it to share a single login across
clients — each fresh Auth::new_oauth2() prompts again. Requires TLS to the
coordinator.
use trino_rust_client::auth::Auth;
use trino_rust_client::{ClientBuilder, Row};
#[tokio::main]
async fn main() {
let cli = ClientBuilder::new("user", "coordinator.example.com")
.secure(true)
.auth(Auth::new_oauth2())
.catalog("catalog")
.build()
.unwrap();
let data = cli.get_all::<Row>("select 1").await.unwrap().into_vec();
for r in data {
println!("{:?}", r)
}
}Supply a custom presentation strategy (instead of opening a browser), or change
the login budget, with Auth::new_oauth2_with_config:
let auth = Auth::new_oauth2_with_config(OAuth2Config {
handler: Arc::new(my_handler),
poll_timeout: Duration::from_secs(600),
..Default::default()
});use trino_rust_client::{ClientBuilder, Row, Trino};
#[tokio::main]
async fn main() {
let cli = ClientBuilder::new("user", "localhost")
.port(8080)
.catalog("catalog")
.build()
.unwrap();
let sql = "select first_name, last_name from users";
let rows = cli.get_all::<Row>(sql.into()).await.unwrap().into_vec();
for row in rows {
let first_name = row.value().get(0).unwrap();
let last_name = row.value().get(1).unwrap();
println!("{} : {}", first_name, last_name);
}
}use trino_rust_client::{ClientBuilder, Trino};
#[derive(Trino, Debug)]
struct User {
id: i64,
name: String,
email: String,
}
#[tokio::main]
async fn main() {
let cli = ClientBuilder::new("user", "localhost")
.port(8080)
.catalog("memory")
.schema("default")
.spooling_encoding("json+zstd") // Enable spooling with compression
.max_concurrent_segments(10) // Optional: control concurrent downloads
.build()
.unwrap();
let sql = "SELECT id, name, email FROM users LIMIT 1000";
let data = cli.get_all::<User>(sql.into()).await.unwrap();
println!("Retrieved {} rows", data.len());
for user in data.as_slice() {
println!("{:?}", user);
}
}MIT