qdrant_client/qdrant_client/
config.rs

1use std::time::Duration;
2
3use crate::{Qdrant, QdrantError};
4
5/// Qdrant client configuration
6///
7/// The client is normally constructed through [`Qdrant::from_url`](crate::Qdrant::from_url):
8///
9/// ```rust,no_run
10/// use qdrant_client::Qdrant;
11/// use qdrant_client::config::CompressionEncoding;
12///
13/// let client = Qdrant::from_url("http://localhost:6334")
14///     .api_key(std::env::var("QDRANT_API_KEY"))
15///     .timeout(std::time::Duration::from_secs(10))
16///     .compression(Some(CompressionEncoding::Gzip))
17///     .build();
18/// ```
19#[derive(Clone)]
20pub struct QdrantConfig {
21    /// Qdrant server URI to connect to
22    pub uri: String,
23
24    /// Timeout for API requests
25    pub timeout: Duration,
26
27    /// Timeout for connecting to the Qdrant server
28    pub connect_timeout: Duration,
29
30    /// Whether to keep idle connections active
31    pub keep_alive_while_idle: bool,
32
33    /// Optional API key or token to use for authorization
34    pub api_key: Option<String>,
35
36    /// Optional compression schema to use for API requests
37    pub compression: Option<CompressionEncoding>,
38
39    /// Whether to check compatibility between the client and server versions
40    pub check_compatibility: bool,
41}
42
43impl QdrantConfig {
44    /// Start configuring a Qdrant client with an URL
45    ///
46    /// ```rust,no_run
47    ///# use qdrant_client::config::QdrantConfig;
48    /// let client = QdrantConfig::from_url("http://localhost:6334").build();
49    /// ```
50    ///
51    /// This is normally done through [`Qdrant::from_url`](crate::Qdrant::from_url).
52    pub fn from_url(url: &str) -> Self {
53        QdrantConfig {
54            uri: url.to_string(),
55            ..Self::default()
56        }
57    }
58
59    /// Set an optional API key
60    ///
61    /// # Examples
62    ///
63    /// A typical use case might be getting the key from an environment variable:
64    ///
65    /// ```rust,no_run
66    /// use qdrant_client::Qdrant;
67    ///
68    /// let client = Qdrant::from_url("http://localhost:6334")
69    ///     .api_key(std::env::var("QDRANT_API_KEY"))
70    ///     .build();
71    /// ```
72    ///
73    /// Or you might get it from some configuration:
74    ///
75    /// ```rust,no_run
76    ///# use std::collections::HashMap;
77    ///# let config: HashMap<&str, String> = HashMap::new();
78    ///# use qdrant_client::Qdrant;
79    /// let client = Qdrant::from_url("http://localhost:6334")
80    ///     .api_key(config.get("api_key"))
81    ///     .build();
82    /// ```
83    pub fn api_key(mut self, api_key: impl AsOptionApiKey) -> Self {
84        self.api_key = api_key.api_key();
85        self
86    }
87
88    /// Keep the connection alive while idle
89    pub fn keep_alive_while_idle(mut self) -> Self {
90        self.keep_alive_while_idle = true;
91        self
92    }
93
94    /// Set the timeout for this client
95    ///
96    /// ```rust,no_run
97    /// use qdrant_client::Qdrant;
98    ///
99    /// let client = Qdrant::from_url("http://localhost:6334")
100    ///     .timeout(std::time::Duration::from_secs(10))
101    ///     .build();
102    /// ```
103    pub fn timeout(mut self, timeout: impl AsTimeout) -> Self {
104        self.timeout = timeout.timeout();
105        self
106    }
107
108    /// Set the connect timeout for this client
109    ///
110    /// ```rust,no_run
111    /// use qdrant_client::Qdrant;
112    ///
113    /// let client = Qdrant::from_url("http://localhost:6334")
114    ///     .connect_timeout(std::time::Duration::from_secs(10))
115    ///     .build();
116    /// ```
117    pub fn connect_timeout(mut self, timeout: impl AsTimeout) -> Self {
118        self.connect_timeout = timeout.timeout();
119        self
120    }
121
122    /// Set the compression to use for this client
123    ///
124    /// ```rust,no_run
125    /// use qdrant_client::Qdrant;
126    /// use qdrant_client::config::CompressionEncoding;
127    ///
128    /// let client = Qdrant::from_url("http://localhost:6334")
129    ///     .compression(Some(CompressionEncoding::Gzip))
130    ///     .build();
131    /// ```
132    pub fn compression(mut self, compression: Option<CompressionEncoding>) -> Self {
133        self.compression = compression;
134        self
135    }
136
137    /// Set an API key
138    ///
139    /// Also see [`api_key()`](fn@Self::api_key).
140    pub fn set_api_key(&mut self, api_key: &str) {
141        self.api_key = Some(api_key.to_string());
142    }
143
144    /// Set the timeout for this client
145    ///
146    /// Also see [`timeout()`](fn@Self::timeout).
147    pub fn set_timeout(&mut self, timeout: Duration) {
148        self.timeout = timeout;
149    }
150
151    /// Set the connection timeout for this client
152    ///
153    /// Also see [`connect_timeout()`](fn@Self::connect_timeout).
154    pub fn set_connect_timeout(&mut self, connect_timeout: Duration) {
155        self.connect_timeout = connect_timeout;
156    }
157
158    /// Set whether to keep the connection alive when idle
159    ///
160    /// Also see [`keep_alive_while_idle()`](fn@Self::keep_alive_while_idle).
161    pub fn set_keep_alive_while_idle(&mut self, keep_alive_while_idle: bool) {
162        self.keep_alive_while_idle = keep_alive_while_idle;
163    }
164
165    /// Set the compression to use for this client
166    ///
167    /// Also see [`compression()`](fn@Self::compression).
168    pub fn set_compression(&mut self, compression: Option<CompressionEncoding>) {
169        self.compression = compression;
170    }
171
172    /// Build the configured [`Qdrant`] client
173    pub fn build(self) -> Result<Qdrant, QdrantError> {
174        Qdrant::new(self)
175    }
176
177    pub fn skip_compatibility_check(mut self) -> Self {
178        self.check_compatibility = false;
179        self
180    }
181}
182
183/// Default Qdrant client configuration.
184///
185/// Connects to `http://localhost:6334` without an API key.
186impl Default for QdrantConfig {
187    fn default() -> Self {
188        Self {
189            uri: String::from("http://localhost:6334"),
190            timeout: Duration::from_secs(5),
191            connect_timeout: Duration::from_secs(5),
192            keep_alive_while_idle: true,
193            api_key: None,
194            compression: None,
195            check_compatibility: true,
196        }
197    }
198}
199
200/// Type of compression to use for requests
201#[derive(Debug, Clone, Copy, PartialEq, Eq)]
202pub enum CompressionEncoding {
203    Gzip,
204}
205
206impl From<CompressionEncoding> for tonic::codec::CompressionEncoding {
207    fn from(encoding: CompressionEncoding) -> Self {
208        match encoding {
209            CompressionEncoding::Gzip => tonic::codec::CompressionEncoding::Gzip,
210        }
211    }
212}
213
214/// Set a timeout from various types
215///
216/// For example:
217///
218/// ```rust
219///# use std::time::Duration;
220///# use qdrant_client::Qdrant;
221///# let mut config = Qdrant::from_url("http://localhost:6334");
222/// config
223///     .timeout(10)
224///     .timeout(Duration::from_secs(10));
225/// ```
226pub trait AsTimeout {
227    fn timeout(self) -> Duration;
228}
229
230impl AsTimeout for Duration {
231    fn timeout(self) -> Duration {
232        self
233    }
234}
235
236impl AsTimeout for u64 {
237    fn timeout(self) -> Duration {
238        Duration::from_secs(self)
239    }
240}
241
242/// Set an optional API key from various types
243///
244/// For example:
245///
246/// ```rust
247///# use std::time::Duration;
248///# use qdrant_client::Qdrant;
249///# let mut config = Qdrant::from_url("http://localhost:6334");
250/// config
251///     .api_key("secret")
252///     .api_key(String::from("secret"))
253///     .api_key(std::env::var("QDRANT_API_KEY"))
254///     .api_key(None::<String>);
255/// ```
256pub trait AsOptionApiKey {
257    fn api_key(self) -> Option<String>;
258}
259
260impl AsOptionApiKey for &str {
261    fn api_key(self) -> Option<String> {
262        Some(self.to_string())
263    }
264}
265
266impl AsOptionApiKey for String {
267    fn api_key(self) -> Option<String> {
268        Some(self)
269    }
270}
271
272impl AsOptionApiKey for Option<String> {
273    fn api_key(self) -> Option<String> {
274        self
275    }
276}
277
278impl AsOptionApiKey for Option<&String> {
279    fn api_key(self) -> Option<String> {
280        self.map(ToOwned::to_owned)
281    }
282}
283
284impl AsOptionApiKey for Option<&str> {
285    fn api_key(self) -> Option<String> {
286        self.map(ToOwned::to_owned)
287    }
288}
289
290impl<E: Sized> AsOptionApiKey for Result<String, E> {
291    fn api_key(self) -> Option<String> {
292        self.ok()
293    }
294}