pub mod run;
pub mod s3;
pub mod upload;
pub use run::{RunContext, close_run, start_run};
pub use upload::{BatchUploader, samples_to_csv};
use std::time::Duration;
use ureq::config::Config as UreqConfig;
const DEFAULT_API_BASE: &str = "https://api.sentinel.sparecores.net";
const API_TIMEOUT_SECS: u64 = 30;
#[derive(Clone)]
pub struct SentinelClient {
pub token: String,
pub api_base: String,
pub agent: ureq::Agent,
}
impl SentinelClient {
pub fn from_env() -> Option<Self> {
let token = std::env::var("SENTINEL_API_TOKEN").ok()?;
if token.is_empty() {
return None;
}
let api_base =
std::env::var("SENTINEL_API_URL").unwrap_or_else(|_| DEFAULT_API_BASE.to_string());
let agent = UreqConfig::builder()
.timeout_global(Some(Duration::from_secs(API_TIMEOUT_SECS)))
.build()
.new_agent();
Some(Self {
token,
api_base,
agent,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_no_token_returns_none() {
unsafe {
std::env::remove_var("SENTINEL_API_TOKEN");
}
assert!(
SentinelClient::from_env().is_none(),
"expected None when SENTINEL_API_TOKEN is unset"
);
}
#[test]
fn test_empty_token_returns_none() {
unsafe {
std::env::set_var("SENTINEL_API_TOKEN", "");
}
let result = SentinelClient::from_env();
unsafe {
std::env::remove_var("SENTINEL_API_TOKEN");
}
assert!(
result.is_none(),
"expected None when SENTINEL_API_TOKEN is empty string"
);
}
#[test]
fn test_valid_token_returns_some_with_defaults() {
unsafe {
std::env::set_var("SENTINEL_API_TOKEN", "my-test-token");
}
unsafe {
std::env::remove_var("SENTINEL_API_URL");
}
let result = SentinelClient::from_env();
unsafe {
std::env::remove_var("SENTINEL_API_TOKEN");
}
let client = result.expect("expected Some when SENTINEL_API_TOKEN is non-empty");
assert_eq!(client.token, "my-test-token");
assert_eq!(client.api_base, DEFAULT_API_BASE);
}
#[test]
fn test_api_url_env_override() {
unsafe {
std::env::set_var("SENTINEL_API_TOKEN", "tok");
}
unsafe {
std::env::set_var("SENTINEL_API_URL", "http://localhost:9999");
}
let result = SentinelClient::from_env();
unsafe {
std::env::remove_var("SENTINEL_API_TOKEN");
}
unsafe {
std::env::remove_var("SENTINEL_API_URL");
}
let client = result.expect("expected Some when token is set");
assert_eq!(client.api_base, "http://localhost:9999");
}
}