Skip to content

Commit 1888337

Browse files
committed
Merge branch 'feat/custom-headers-builder' of github.com:qdrant/rust-client into feat/custom-headers-builder
2 parents 5614833 + 0dcc9cd commit 1888337

File tree

2 files changed

+250
-1
lines changed

2 files changed

+250
-1
lines changed

tests/snippet_tests/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ mod test_delete_snapshot;
2121
mod test_delete_vectors;
2222
mod test_discover_batch_points;
2323
mod test_discover_points;
24+
mod test_external_api_keys;
2425
mod test_facets;
2526
mod test_get_collection;
2627
mod test_get_collection_aliases;
@@ -57,4 +58,4 @@ mod test_upsert_image;
5758
mod test_upsert_points;
5859
mod test_upsert_points_fallback_shard_key;
5960
mod test_upsert_points_insert_only;
60-
mod test_upsert_points_with_condition;
61+
mod test_upsert_points_with_condition;
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
use std::collections::HashMap;
2+
3+
use qdrant_client::qdrant::{
4+
CreateCollectionBuilder, Distance, Document, PointStruct, Query, QueryPointsBuilder,
5+
UpsertPointsBuilder, VectorParamsBuilder,
6+
};
7+
use qdrant_client::{Payload, Qdrant};
8+
use serde_json::json;
9+
10+
const PROXY_URL: &str = "http://localhost:6334";
11+
const UPSERT_COLLECTION_NAME: &str = "test_external_api_keys_upsert";
12+
const QUERY_COLLECTION_NAME: &str = "test_external_api_keys_query";
13+
const DUAL_OPENAI_COLLECTION_NAME: &str = "test_external_api_keys_dual_openai";
14+
const DUAL_COHERE_COLLECTION_NAME: &str = "test_external_api_keys_dual_cohere";
15+
const OPENAI_MODEL: &str = "openai/text-embedding-3-small";
16+
const OPENAI_VECTOR_SIZE: u64 = 1536;
17+
const COHERE_MODEL: &str = "cohere/embed-english-v3.0";
18+
const COHERE_VECTOR_SIZE: u64 = 1024;
19+
20+
fn create_client_with_external_keys(external_api_keys: HashMap<String, String>) -> Qdrant {
21+
let mut builder = Qdrant::from_url(PROXY_URL)
22+
.skip_compatibility_check()
23+
.api_key("1234")
24+
.timeout(30u64);
25+
for (key, value) in external_api_keys {
26+
builder = builder.header(key, value);
27+
}
28+
builder.build().expect("Failed to build client")
29+
}
30+
31+
async fn setup_collection(client: &Qdrant, collection_name: &str, vector_size: u64) {
32+
let _ = client.delete_collection(collection_name).await;
33+
34+
client
35+
.create_collection(
36+
CreateCollectionBuilder::new(collection_name)
37+
.vectors_config(VectorParamsBuilder::new(vector_size, Distance::Cosine)),
38+
)
39+
.await
40+
.expect("Failed to create collection");
41+
}
42+
43+
fn cohere_document(text: impl Into<String>, input_type: &'static str) -> Document {
44+
Document {
45+
text: text.into(),
46+
model: COHERE_MODEL.to_string(),
47+
options: HashMap::from([("input_type".to_string(), input_type.into())]),
48+
}
49+
}
50+
51+
#[tokio::test]
52+
async fn test_upsert_with_external_api_keys() {
53+
let Some(openai_api_key) = std::env::var("OPENAI_API_KEY").ok() else {
54+
eprintln!("Skipping test_upsert_with_external_api_keys: OPENAI_API_KEY is not set");
55+
return;
56+
};
57+
let collection_name = UPSERT_COLLECTION_NAME;
58+
let client = create_client_with_external_keys(HashMap::from([(
59+
"openai-api-key".to_string(),
60+
openai_api_key,
61+
)]));
62+
setup_collection(&client, collection_name, OPENAI_VECTOR_SIZE).await;
63+
64+
let doc = Document::new("Qdrant is a vector search engine", OPENAI_MODEL);
65+
66+
let result = client
67+
.upsert_points(
68+
UpsertPointsBuilder::new(
69+
collection_name,
70+
vec![PointStruct::new(
71+
1,
72+
doc,
73+
Payload::try_from(json!({"source": "test"})).unwrap(),
74+
)],
75+
)
76+
.wait(true),
77+
)
78+
.await;
79+
80+
assert!(
81+
result.is_ok(),
82+
"Upsert with external API keys failed: {result:?}"
83+
);
84+
85+
let _ = client.delete_collection(collection_name).await;
86+
}
87+
88+
#[tokio::test]
89+
async fn test_query_with_external_api_keys() {
90+
let Some(openai_api_key) = std::env::var("OPENAI_API_KEY").ok() else {
91+
eprintln!("Skipping test_query_with_external_api_keys: OPENAI_API_KEY is not set");
92+
return;
93+
};
94+
let collection_name = QUERY_COLLECTION_NAME;
95+
let client = create_client_with_external_keys(HashMap::from([(
96+
"openai-api-key".to_string(),
97+
openai_api_key,
98+
)]));
99+
setup_collection(&client, collection_name, OPENAI_VECTOR_SIZE).await;
100+
101+
// Upsert a point first
102+
let doc = Document::new("Qdrant is a vector search engine", OPENAI_MODEL);
103+
client
104+
.upsert_points(
105+
UpsertPointsBuilder::new(
106+
collection_name,
107+
vec![PointStruct::new(
108+
1,
109+
doc,
110+
Payload::try_from(json!({"source": "test"})).unwrap(),
111+
)],
112+
)
113+
.wait(true),
114+
)
115+
.await
116+
.expect("Upsert failed");
117+
118+
// Query with a document (server-side inference)
119+
let query_doc = Document::new("vector database", OPENAI_MODEL);
120+
121+
let result = client
122+
.query(
123+
QueryPointsBuilder::new(collection_name)
124+
.query(Query::new_nearest(query_doc))
125+
.limit(1)
126+
.with_payload(true),
127+
)
128+
.await;
129+
130+
assert!(
131+
result.is_ok(),
132+
"Query with external API keys failed: {result:?}"
133+
);
134+
135+
let response = result.unwrap();
136+
assert_eq!(response.result.len(), 1);
137+
assert!(response.result[0].payload.contains_key("source"));
138+
139+
let _ = client.delete_collection(collection_name).await;
140+
}
141+
142+
#[tokio::test]
143+
async fn test_query_with_two_external_api_providers() {
144+
let Some(openai_api_key) = std::env::var("OPENAI_API_KEY").ok() else {
145+
eprintln!("Skipping test_query_with_two_external_api_providers: OPENAI_API_KEY is not set");
146+
return;
147+
};
148+
let Some(cohere_api_key) = std::env::var("COHERE_API_KEY").ok() else {
149+
eprintln!("Skipping test_query_with_two_external_api_providers: COHERE_API_KEY is not set");
150+
return;
151+
};
152+
153+
let client = create_client_with_external_keys(HashMap::from([
154+
("openai-api-key".to_string(), openai_api_key),
155+
("cohere-api-key".to_string(), cohere_api_key),
156+
]));
157+
158+
setup_collection(&client, DUAL_OPENAI_COLLECTION_NAME, OPENAI_VECTOR_SIZE).await;
159+
setup_collection(&client, DUAL_COHERE_COLLECTION_NAME, COHERE_VECTOR_SIZE).await;
160+
161+
let openai_doc = Document::new("OpenAI provider document", OPENAI_MODEL);
162+
let cohere_doc = cohere_document("Cohere provider document", "search_document");
163+
164+
let openai_upsert = client
165+
.upsert_points(
166+
UpsertPointsBuilder::new(
167+
DUAL_OPENAI_COLLECTION_NAME,
168+
vec![PointStruct::new(
169+
1,
170+
openai_doc,
171+
Payload::try_from(json!({"provider": "openai"})).unwrap(),
172+
)],
173+
)
174+
.wait(true),
175+
)
176+
.await;
177+
assert!(
178+
openai_upsert.is_ok(),
179+
"OpenAI upsert with external API keys failed: {openai_upsert:?}"
180+
);
181+
182+
let cohere_upsert = client
183+
.upsert_points(
184+
UpsertPointsBuilder::new(
185+
DUAL_COHERE_COLLECTION_NAME,
186+
vec![PointStruct::new(
187+
1,
188+
cohere_doc,
189+
Payload::try_from(json!({"provider": "cohere"})).unwrap(),
190+
)],
191+
)
192+
.wait(true),
193+
)
194+
.await;
195+
assert!(
196+
cohere_upsert.is_ok(),
197+
"Cohere upsert with external API keys failed: {cohere_upsert:?}"
198+
);
199+
200+
let openai_query = client
201+
.query(
202+
QueryPointsBuilder::new(DUAL_OPENAI_COLLECTION_NAME)
203+
.query(Query::new_nearest(Document::new(
204+
"OpenAI provider query",
205+
OPENAI_MODEL,
206+
)))
207+
.limit(1)
208+
.with_payload(true),
209+
)
210+
.await;
211+
assert!(
212+
openai_query.is_ok(),
213+
"OpenAI query with external API keys failed: {openai_query:?}"
214+
);
215+
216+
let cohere_query = client
217+
.query(
218+
QueryPointsBuilder::new(DUAL_COHERE_COLLECTION_NAME)
219+
.query(Query::new_nearest(cohere_document(
220+
"Cohere provider query",
221+
"search_query",
222+
)))
223+
.limit(1)
224+
.with_payload(true),
225+
)
226+
.await;
227+
assert!(
228+
cohere_query.is_ok(),
229+
"Cohere query with external API keys failed: {cohere_query:?}"
230+
);
231+
232+
let openai_response = openai_query.unwrap();
233+
assert_eq!(openai_response.result.len(), 1);
234+
assert_eq!(
235+
openai_response.result[0].payload["provider"],
236+
"openai".into()
237+
);
238+
239+
let cohere_response = cohere_query.unwrap();
240+
assert_eq!(cohere_response.result.len(), 1);
241+
assert_eq!(
242+
cohere_response.result[0].payload["provider"],
243+
"cohere".into()
244+
);
245+
246+
let _ = client.delete_collection(DUAL_OPENAI_COLLECTION_NAME).await;
247+
let _ = client.delete_collection(DUAL_COHERE_COLLECTION_NAME).await;
248+
}

0 commit comments

Comments
 (0)