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}