1use std::env;
7use std::sync::Arc;
8
9pub mod containers_api;
10pub mod graphs_api;
11pub mod inference_api;
12pub mod models;
13pub mod openapi_paths;
14pub mod optimization_api;
15pub mod pools_api;
16mod transport;
17pub mod tunnels_api;
18pub mod verifiers_api;
19
20pub use types::SynthError as Error;
21pub use types::{Result, SynthError};
22
23pub use containers_api::ContainersClient;
24pub use graphs_api::GraphsClient;
25pub use inference_api::InferenceClient;
26pub use optimization_api::OptimizationClient;
27pub use pools_api::PoolsClient;
28pub use tunnels_api::TunnelsClient;
29pub use verifiers_api::VerifiersClient;
30
31mod types;
32
33pub const VERSION: &str = env!("CARGO_PKG_VERSION");
35
36pub const DEFAULT_BASE_URL: &str = synth_ai_core::urls::DEFAULT_BACKEND_URL;
38
39pub const API_KEY_ENV: &str = "SYNTH_API_KEY";
41
42#[derive(Clone)]
44pub struct SynthClient {
45 transport: Arc<transport::Transport>,
46}
47
48impl SynthClient {
49 pub fn new(api_key: impl Into<String>, base_url: Option<&str>) -> Result<Self> {
51 let base_url = base_url.unwrap_or(DEFAULT_BASE_URL).to_string();
52 let transport = transport::Transport::new(api_key.into(), base_url)?;
53 Ok(Self {
54 transport: Arc::new(transport),
55 })
56 }
57
58 pub fn from_env() -> Result<Self> {
60 let api_key = env::var(API_KEY_ENV).map_err(|_| SynthError::MissingApiKey)?;
61 let base_url = env::var("SYNTH_BASE_URL")
62 .ok()
63 .or_else(|| env::var("SYNTH_BACKEND_URL").ok());
64 Self::new(api_key, base_url.as_deref())
65 }
66
67 pub fn base_url(&self) -> &str {
68 self.transport.base_url()
69 }
70
71 pub fn optimization(&self) -> OptimizationClient {
72 OptimizationClient::new(self.transport.clone())
73 }
74
75 pub fn inference(&self) -> InferenceClient {
76 InferenceClient::new(self.transport.clone())
77 }
78
79 pub fn graphs(&self) -> GraphsClient {
80 GraphsClient::new(self.transport.clone())
81 }
82
83 pub fn verifiers(&self) -> VerifiersClient {
84 VerifiersClient::new(self.transport.clone())
85 }
86
87 pub fn pools(&self) -> PoolsClient {
88 PoolsClient::new(self.transport.clone())
89 }
90
91 pub fn containers(&self) -> ContainersClient {
92 ContainersClient::new(self.transport.clone())
93 }
94
95 pub fn tunnels(&self) -> TunnelsClient {
96 TunnelsClient::new(self.transport.clone())
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn default_base_url_is_set() {
106 assert!(!DEFAULT_BASE_URL.is_empty());
107 }
108
109 #[test]
110 fn from_env_without_key_fails() {
111 env::remove_var(API_KEY_ENV);
112 let result = SynthClient::from_env();
113 assert!(result.is_err());
114 }
115}