Skip to main content

linger_openai_sdk/
config.rs

1use crate::error::LingerError;
2use crate::retry::{NoopRetrySleeper, RetryPolicy, RetrySleeper};
3use std::fmt;
4use std::sync::Arc;
5
6/// EN: SDK client configuration.
7/// 中文:SDK 客户端配置。
8#[derive(Clone)]
9#[non_exhaustive]
10pub struct ClientConfig {
11    api_key: String,
12    base_url: String,
13    organization: Option<String>,
14    project: Option<String>,
15    retry_policy: RetryPolicy,
16    retry_sleeper: Arc<dyn RetrySleeper>,
17}
18
19impl ClientConfig {
20    /// EN: Starts building a client configuration.
21    /// 中文:开始构建客户端配置。
22    pub fn builder() -> ClientConfigBuilder {
23        ClientConfigBuilder::default()
24    }
25
26    /// EN: Returns the configured API key.
27    /// 中文:返回已配置的 API key。
28    pub(crate) fn api_key(&self) -> &str {
29        &self.api_key
30    }
31
32    /// EN: Returns the base API URL.
33    /// 中文:返回 API 基础 URL。
34    pub fn base_url(&self) -> &str {
35        &self.base_url
36    }
37
38    /// EN: Returns the configured organization header value.
39    /// 中文:返回已配置的组织请求头值。
40    pub fn organization(&self) -> Option<&str> {
41        self.organization.as_deref()
42    }
43
44    /// EN: Returns the configured project header value.
45    /// 中文:返回已配置的项目请求头值。
46    pub fn project(&self) -> Option<&str> {
47        self.project.as_deref()
48    }
49
50    /// EN: Returns the configured retry policy.
51    /// 中文:返回已配置的重试策略。
52    pub fn retry_policy(&self) -> &RetryPolicy {
53        &self.retry_policy
54    }
55
56    /// EN: Returns the configured retry sleeper.
57    /// 中文:返回已配置的重试休眠器。
58    pub fn retry_sleeper(&self) -> Arc<dyn RetrySleeper> {
59        self.retry_sleeper.clone()
60    }
61}
62
63impl fmt::Debug for ClientConfig {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        f.debug_struct("ClientConfig")
66            .field("api_key", &"<redacted>")
67            .field("base_url", &self.base_url)
68            .field(
69                "organization",
70                &self.organization.as_ref().map(|_| "<redacted>"),
71            )
72            .field("project", &self.project.as_ref().map(|_| "<redacted>"))
73            .field("retry_policy", &self.retry_policy)
74            .field("retry_sleeper", &self.retry_sleeper)
75            .finish()
76    }
77}
78
79/// EN: Builder for SDK client configuration.
80/// 中文:SDK 客户端配置构建器。
81#[derive(Clone, Debug)]
82#[non_exhaustive]
83pub struct ClientConfigBuilder {
84    api_key: Option<String>,
85    base_url: String,
86    organization: Option<String>,
87    project: Option<String>,
88    retry_policy: RetryPolicy,
89    retry_sleeper: Arc<dyn RetrySleeper>,
90}
91
92impl Default for ClientConfigBuilder {
93    fn default() -> Self {
94        Self {
95            api_key: None,
96            base_url: "https://api.openai.com".to_string(),
97            organization: None,
98            project: None,
99            retry_policy: RetryPolicy::default(),
100            retry_sleeper: Arc::new(NoopRetrySleeper),
101        }
102    }
103}
104
105impl ClientConfigBuilder {
106    /// EN: Sets the OpenAI API key used for bearer authentication.
107    /// 中文:设置用于 Bearer 认证的 OpenAI API key。
108    pub fn api_key(mut self, api_key: impl Into<String>) -> Self {
109        self.api_key = Some(api_key.into());
110        self
111    }
112
113    /// EN: Sets the OpenAI API base URL.
114    /// 中文:设置 OpenAI API 基础 URL。
115    pub fn base_url(mut self, base_url: impl Into<String>) -> Self {
116        self.base_url = base_url.into();
117        self
118    }
119
120    /// EN: Sets the optional OpenAI organization header.
121    /// 中文:设置可选的 OpenAI 组织请求头。
122    pub fn organization(mut self, organization: impl Into<String>) -> Self {
123        self.organization = Some(organization.into());
124        self
125    }
126
127    /// EN: Sets the optional OpenAI project header.
128    /// 中文:设置可选的 OpenAI 项目请求头。
129    pub fn project(mut self, project: impl Into<String>) -> Self {
130        self.project = Some(project.into());
131        self
132    }
133
134    /// EN: Sets the retry policy.
135    /// 中文:设置重试策略。
136    pub fn retry_policy(mut self, retry_policy: RetryPolicy) -> Self {
137        self.retry_policy = retry_policy;
138        self
139    }
140
141    /// EN: Sets the retry sleeper used between retry attempts.
142    /// 中文:设置两次重试之间使用的休眠器。
143    pub fn retry_sleeper(mut self, retry_sleeper: Arc<dyn RetrySleeper>) -> Self {
144        self.retry_sleeper = retry_sleeper;
145        self
146    }
147
148    /// EN: Builds and validates the client configuration.
149    /// 中文:构建并校验客户端配置。
150    pub fn build(self) -> Result<ClientConfig, LingerError> {
151        let api_key = self
152            .api_key
153            .filter(|value| !value.trim().is_empty())
154            .ok_or_else(|| LingerError::invalid_config("api_key is required"))?;
155        if self.base_url.trim().is_empty() {
156            return Err(LingerError::invalid_config("base_url is required"));
157        }
158        Ok(ClientConfig {
159            api_key,
160            base_url: self.base_url.trim_end_matches('/').to_string(),
161            organization: self.organization,
162            project: self.project,
163            retry_policy: self.retry_policy,
164            retry_sleeper: self.retry_sleeper,
165        })
166    }
167}