turbopuffer_client/
lib.rs1use error::Error;
2use response::{
3 DeleteResponse,
4 QueryResponse,
5 ResponseVector,
6 UpsertResponse,
7};
8use serde_json::{
9 from_value,
10 Value,
11};
12
13pub mod error;
14pub mod response;
15
16const BASE_URL: &str = "https://api.turbopuffer.com/v1";
17
18#[derive(Clone)]
19pub struct Client {
20 api_key: String,
21 client: reqwest::Client,
22}
23
24impl Client {
25 pub fn new(api_key: &str) -> Self {
39 Self {
40 api_key: api_key.to_string(),
41 client: reqwest::Client::new(),
42 }
43 }
44
45 pub fn namespace<'a>(&'a self, namespace: &'a str) -> NamespacedClient<'a> {
56 NamespacedClient {
57 client: self,
58 namespace,
59 }
60 }
61}
62
63pub struct NamespacedClient<'a> {
64 client: &'a Client,
65 namespace: &'a str,
66}
67
68impl<'a> NamespacedClient<'a> {
69 pub async fn upsert(&self, body: &Value) -> Result<UpsertResponse, Error> {
94 let url = format!("{BASE_URL}/vectors/{}", &self.namespace);
95 let res = self
96 .client
97 .client
98 .post(url)
99 .header("Authorization", format!("Bearer {}", self.client.api_key))
100 .header("Content-Type", "application/json")
101 .json(body)
102 .send()
103 .await?;
104
105 let body = res.text().await.map_err(error::request_error)?;
106 let value = serde_json::from_str::<Value>(&body)
107 .map_err(|e| error::non_json(e, body))?;
108
109 from_value::<UpsertResponse>(value.clone())
111 .map_err(|e| error::invalid_response(e, value))
112 }
113
114 pub async fn query(&self, body: &Value) -> Result<QueryResponse, Error> {
136 let url = format!("{BASE_URL}/vectors/{}/query", &self.namespace);
137 let res = self
138 .client
139 .client
140 .post(url)
141 .header("Authorization", format!("Bearer {}", self.client.api_key))
142 .header("Content-Type", "application/json")
143 .json(body)
144 .send()
145 .await?;
146
147 let body = res.text().await.map_err(error::request_error)?;
148 let value = serde_json::from_str::<Value>(&body)
149 .map_err(|e| error::non_json(e, body))?;
150
151 let vectors = from_value::<Vec<ResponseVector>>(value.clone())
153 .map_err(|e| error::invalid_response(e, value))?;
154 Ok(QueryResponse { vectors })
155 }
156
157 pub async fn delete(&self) -> Result<DeleteResponse, Error> {
171 let url = format!("{BASE_URL}/vectors/{}", &self.namespace);
172 let res = self
173 .client
174 .client
175 .delete(url)
176 .header("Authorization", format!("Bearer {}", self.client.api_key))
177 .header("Content-Type", "application/json")
178 .send()
179 .await?;
180
181 let body = res.text().await.map_err(error::request_error)?;
182 let value = serde_json::from_str::<Value>(&body)
183 .map_err(|e| error::non_json(e, body))?;
184
185 from_value::<DeleteResponse>(value.clone())
187 .map_err(|e| error::invalid_response(e, value))
188 }
189}