Skip to main content

langfuse_client_base/apis/
datasets_api.rs

1/*
2 * server
3 *
4 * ## Real-time data  The only real-time path to get tracing data is to ingest via OpenTelemetry (`POST /api/public/otel/v1/traces`) and retrieve via Observations API v2 (`GET /api/public/v2/observations`) and Metrics API v2 (`GET /api/public/v2/metrics`). Other public API write and read endpoints can delay data by about 10 minutes. Direct OpenTelemetry exporters must send the `x-langfuse-ingestion-version: 4` header; current Python and JS SDKs already do. See the [Public API docs](https://langfuse.com/docs/api-and-data-platform/features/public-api) and [real-time ingestion](https://langfuse.com/integrations/native/opentelemetry.md#real-time-ingestion).  ## Authentication  Authenticate with the API using [Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication), get API keys in the project settings:  - username: Langfuse Public Key - password: Langfuse Secret Key  ## Exports  - OpenAPI spec: https://cloud.langfuse.com/generated/api/openapi.yml - Self-hosted deployments: interactive API reference at `/api/docs` and OpenAPI spec at `/api/openapi.yaml`
5 *
6 * The version of the OpenAPI document:
7 *
8 * Generated by: https://openapi-generator.tech
9 */
10
11use super::{configuration, ContentType, Error};
12use crate::{apis::ResponseContent, models};
13use reqwest;
14use serde::{de::Error as _, Deserialize, Serialize};
15
16/// struct for typed errors of method [`datasets_create`]
17#[derive(Debug, Clone, Serialize, Deserialize)]
18#[serde(untagged)]
19pub enum DatasetsCreateError {
20    Status400(serde_json::Value),
21    Status401(serde_json::Value),
22    Status403(serde_json::Value),
23    Status404(serde_json::Value),
24    Status405(serde_json::Value),
25    UnknownValue(serde_json::Value),
26}
27
28/// struct for typed errors of method [`datasets_delete_run`]
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(untagged)]
31pub enum DatasetsDeleteRunError {
32    Status400(serde_json::Value),
33    Status401(serde_json::Value),
34    Status403(serde_json::Value),
35    Status404(serde_json::Value),
36    Status405(serde_json::Value),
37    UnknownValue(serde_json::Value),
38}
39
40/// struct for typed errors of method [`datasets_get`]
41#[derive(Debug, Clone, Serialize, Deserialize)]
42#[serde(untagged)]
43pub enum DatasetsGetError {
44    Status400(serde_json::Value),
45    Status401(serde_json::Value),
46    Status403(serde_json::Value),
47    Status404(serde_json::Value),
48    Status405(serde_json::Value),
49    UnknownValue(serde_json::Value),
50}
51
52/// struct for typed errors of method [`datasets_get_run`]
53#[derive(Debug, Clone, Serialize, Deserialize)]
54#[serde(untagged)]
55pub enum DatasetsGetRunError {
56    Status400(serde_json::Value),
57    Status401(serde_json::Value),
58    Status403(serde_json::Value),
59    Status404(serde_json::Value),
60    Status405(serde_json::Value),
61    UnknownValue(serde_json::Value),
62}
63
64/// struct for typed errors of method [`datasets_get_runs`]
65#[derive(Debug, Clone, Serialize, Deserialize)]
66#[serde(untagged)]
67pub enum DatasetsGetRunsError {
68    Status400(serde_json::Value),
69    Status401(serde_json::Value),
70    Status403(serde_json::Value),
71    Status404(serde_json::Value),
72    Status405(serde_json::Value),
73    UnknownValue(serde_json::Value),
74}
75
76/// struct for typed errors of method [`datasets_list`]
77#[derive(Debug, Clone, Serialize, Deserialize)]
78#[serde(untagged)]
79pub enum DatasetsListError {
80    Status400(serde_json::Value),
81    Status401(serde_json::Value),
82    Status403(serde_json::Value),
83    Status404(serde_json::Value),
84    Status405(serde_json::Value),
85    UnknownValue(serde_json::Value),
86}
87
88/// Create a dataset
89#[bon::builder]
90pub async fn datasets_create(
91    configuration: &configuration::Configuration,
92    create_dataset_request: models::CreateDatasetRequest,
93) -> Result<models::Dataset, Error<DatasetsCreateError>> {
94    // add a prefix to parameters to efficiently prevent name collisions
95    let p_body_create_dataset_request = create_dataset_request;
96
97    let uri_str = format!("{}/api/public/v2/datasets", configuration.base_path);
98    let mut req_builder = configuration
99        .client
100        .request(reqwest::Method::POST, &uri_str);
101
102    if let Some(ref user_agent) = configuration.user_agent {
103        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
104    }
105    if let Some(ref auth_conf) = configuration.basic_auth {
106        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
107    };
108    req_builder = req_builder.json(&p_body_create_dataset_request);
109
110    let req = req_builder.build()?;
111    let resp = configuration.client.execute(req).await?;
112
113    let status = resp.status();
114    let content_type = resp
115        .headers()
116        .get("content-type")
117        .and_then(|v| v.to_str().ok())
118        .unwrap_or("application/octet-stream");
119    let content_type = super::ContentType::from(content_type);
120
121    if !status.is_client_error() && !status.is_server_error() {
122        let content = resp.text().await?;
123        match content_type {
124            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
125            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Dataset`"))),
126            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Dataset`")))),
127        }
128    } else {
129        let content = resp.text().await?;
130        let entity: Option<DatasetsCreateError> = serde_json::from_str(&content).ok();
131        Err(Error::ResponseError(ResponseContent {
132            status,
133            content,
134            entity,
135        }))
136    }
137}
138
139/// **Deprecated:** On Langfuse Cloud, Langfuse v3 is deprecated and this endpoint will be removed on November 16, 2026. In Langfuse v4, dataset runs are replaced by experiments. Self-hosted deployments are unaffected by this date; the endpoint becomes unavailable when they upgrade to Langfuse v4. See the [Langfuse v3 to v4 upgrade guide](https://langfuse.com/self-hosting/upgrade/upgrade-guides/upgrade-v3-to-v4).  Delete a dataset run and all its run items. This action is irreversible.
140#[deprecated]
141#[bon::builder]
142pub async fn datasets_delete_run(
143    configuration: &configuration::Configuration,
144    dataset_name: &str,
145    run_name: &str,
146) -> Result<models::DeleteDatasetRunResponse, Error<DatasetsDeleteRunError>> {
147    // add a prefix to parameters to efficiently prevent name collisions
148    let p_path_dataset_name = dataset_name;
149    let p_path_run_name = run_name;
150
151    let uri_str = format!(
152        "{}/api/public/datasets/{datasetName}/runs/{runName}",
153        configuration.base_path,
154        datasetName = crate::apis::urlencode(p_path_dataset_name),
155        runName = crate::apis::urlencode(p_path_run_name)
156    );
157    let mut req_builder = configuration
158        .client
159        .request(reqwest::Method::DELETE, &uri_str);
160
161    if let Some(ref user_agent) = configuration.user_agent {
162        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
163    }
164    if let Some(ref auth_conf) = configuration.basic_auth {
165        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
166    };
167
168    let req = req_builder.build()?;
169    let resp = configuration.client.execute(req).await?;
170
171    let status = resp.status();
172    let content_type = resp
173        .headers()
174        .get("content-type")
175        .and_then(|v| v.to_str().ok())
176        .unwrap_or("application/octet-stream");
177    let content_type = super::ContentType::from(content_type);
178
179    if !status.is_client_error() && !status.is_server_error() {
180        let content = resp.text().await?;
181        match content_type {
182            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
183            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DeleteDatasetRunResponse`"))),
184            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::DeleteDatasetRunResponse`")))),
185        }
186    } else {
187        let content = resp.text().await?;
188        let entity: Option<DatasetsDeleteRunError> = serde_json::from_str(&content).ok();
189        Err(Error::ResponseError(ResponseContent {
190            status,
191            content,
192            entity,
193        }))
194    }
195}
196
197/// Get a dataset
198#[bon::builder]
199pub async fn datasets_get(
200    configuration: &configuration::Configuration,
201    dataset_name: &str,
202) -> Result<models::Dataset, Error<DatasetsGetError>> {
203    // add a prefix to parameters to efficiently prevent name collisions
204    let p_path_dataset_name = dataset_name;
205
206    let uri_str = format!(
207        "{}/api/public/v2/datasets/{datasetName}",
208        configuration.base_path,
209        datasetName = crate::apis::urlencode(p_path_dataset_name)
210    );
211    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
212
213    if let Some(ref user_agent) = configuration.user_agent {
214        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
215    }
216    if let Some(ref auth_conf) = configuration.basic_auth {
217        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
218    };
219
220    let req = req_builder.build()?;
221    let resp = configuration.client.execute(req).await?;
222
223    let status = resp.status();
224    let content_type = resp
225        .headers()
226        .get("content-type")
227        .and_then(|v| v.to_str().ok())
228        .unwrap_or("application/octet-stream");
229    let content_type = super::ContentType::from(content_type);
230
231    if !status.is_client_error() && !status.is_server_error() {
232        let content = resp.text().await?;
233        match content_type {
234            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
235            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Dataset`"))),
236            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Dataset`")))),
237        }
238    } else {
239        let content = resp.text().await?;
240        let entity: Option<DatasetsGetError> = serde_json::from_str(&content).ok();
241        Err(Error::ResponseError(ResponseContent {
242            status,
243            content,
244            entity,
245        }))
246    }
247}
248
249/// **Deprecated:** On Langfuse Cloud, Langfuse v3 is deprecated and this endpoint will be removed on November 16, 2026. In Langfuse v4, dataset runs are replaced by experiments; use GET /api/public/experiments instead. Self-hosted deployments are unaffected by this date; the endpoint becomes unavailable when they upgrade to Langfuse v4. See the [Langfuse v3 to v4 upgrade guide](https://langfuse.com/self-hosting/upgrade/upgrade-guides/upgrade-v3-to-v4).  Get a dataset run and its items
250#[deprecated]
251#[bon::builder]
252pub async fn datasets_get_run(
253    configuration: &configuration::Configuration,
254    dataset_name: &str,
255    run_name: &str,
256) -> Result<models::DatasetRunWithItems, Error<DatasetsGetRunError>> {
257    // add a prefix to parameters to efficiently prevent name collisions
258    let p_path_dataset_name = dataset_name;
259    let p_path_run_name = run_name;
260
261    let uri_str = format!(
262        "{}/api/public/datasets/{datasetName}/runs/{runName}",
263        configuration.base_path,
264        datasetName = crate::apis::urlencode(p_path_dataset_name),
265        runName = crate::apis::urlencode(p_path_run_name)
266    );
267    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
268
269    if let Some(ref user_agent) = configuration.user_agent {
270        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
271    }
272    if let Some(ref auth_conf) = configuration.basic_auth {
273        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
274    };
275
276    let req = req_builder.build()?;
277    let resp = configuration.client.execute(req).await?;
278
279    let status = resp.status();
280    let content_type = resp
281        .headers()
282        .get("content-type")
283        .and_then(|v| v.to_str().ok())
284        .unwrap_or("application/octet-stream");
285    let content_type = super::ContentType::from(content_type);
286
287    if !status.is_client_error() && !status.is_server_error() {
288        let content = resp.text().await?;
289        match content_type {
290            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
291            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DatasetRunWithItems`"))),
292            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::DatasetRunWithItems`")))),
293        }
294    } else {
295        let content = resp.text().await?;
296        let entity: Option<DatasetsGetRunError> = serde_json::from_str(&content).ok();
297        Err(Error::ResponseError(ResponseContent {
298            status,
299            content,
300            entity,
301        }))
302    }
303}
304
305/// **Deprecated:** On Langfuse Cloud, Langfuse v3 is deprecated and this endpoint will be removed on November 16, 2026. In Langfuse v4, dataset runs are replaced by experiments; use GET /api/public/experiments instead. Self-hosted deployments are unaffected by this date; the endpoint becomes unavailable when they upgrade to Langfuse v4. See the [Langfuse v3 to v4 upgrade guide](https://langfuse.com/self-hosting/upgrade/upgrade-guides/upgrade-v3-to-v4).  Get dataset runs
306#[deprecated]
307#[bon::builder]
308pub async fn datasets_get_runs(
309    configuration: &configuration::Configuration,
310    dataset_name: &str,
311    page: Option<i32>,
312    limit: Option<i32>,
313) -> Result<models::PaginatedDatasetRuns, Error<DatasetsGetRunsError>> {
314    // add a prefix to parameters to efficiently prevent name collisions
315    let p_path_dataset_name = dataset_name;
316    let p_query_page = page;
317    let p_query_limit = limit;
318
319    let uri_str = format!(
320        "{}/api/public/datasets/{datasetName}/runs",
321        configuration.base_path,
322        datasetName = crate::apis::urlencode(p_path_dataset_name)
323    );
324    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
325
326    if let Some(ref param_value) = p_query_page {
327        req_builder = req_builder.query(&[("page", &param_value.to_string())]);
328    }
329    if let Some(ref param_value) = p_query_limit {
330        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
331    }
332    if let Some(ref user_agent) = configuration.user_agent {
333        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
334    }
335    if let Some(ref auth_conf) = configuration.basic_auth {
336        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
337    };
338
339    let req = req_builder.build()?;
340    let resp = configuration.client.execute(req).await?;
341
342    let status = resp.status();
343    let content_type = resp
344        .headers()
345        .get("content-type")
346        .and_then(|v| v.to_str().ok())
347        .unwrap_or("application/octet-stream");
348    let content_type = super::ContentType::from(content_type);
349
350    if !status.is_client_error() && !status.is_server_error() {
351        let content = resp.text().await?;
352        match content_type {
353            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
354            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PaginatedDatasetRuns`"))),
355            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PaginatedDatasetRuns`")))),
356        }
357    } else {
358        let content = resp.text().await?;
359        let entity: Option<DatasetsGetRunsError> = serde_json::from_str(&content).ok();
360        Err(Error::ResponseError(ResponseContent {
361            status,
362            content,
363            entity,
364        }))
365    }
366}
367
368/// Get all datasets
369#[bon::builder]
370pub async fn datasets_list(
371    configuration: &configuration::Configuration,
372    page: Option<i32>,
373    limit: Option<i32>,
374) -> Result<models::PaginatedDatasets, Error<DatasetsListError>> {
375    // add a prefix to parameters to efficiently prevent name collisions
376    let p_query_page = page;
377    let p_query_limit = limit;
378
379    let uri_str = format!("{}/api/public/v2/datasets", configuration.base_path);
380    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
381
382    if let Some(ref param_value) = p_query_page {
383        req_builder = req_builder.query(&[("page", &param_value.to_string())]);
384    }
385    if let Some(ref param_value) = p_query_limit {
386        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
387    }
388    if let Some(ref user_agent) = configuration.user_agent {
389        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
390    }
391    if let Some(ref auth_conf) = configuration.basic_auth {
392        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
393    };
394
395    let req = req_builder.build()?;
396    let resp = configuration.client.execute(req).await?;
397
398    let status = resp.status();
399    let content_type = resp
400        .headers()
401        .get("content-type")
402        .and_then(|v| v.to_str().ok())
403        .unwrap_or("application/octet-stream");
404    let content_type = super::ContentType::from(content_type);
405
406    if !status.is_client_error() && !status.is_server_error() {
407        let content = resp.text().await?;
408        match content_type {
409            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
410            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PaginatedDatasets`"))),
411            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PaginatedDatasets`")))),
412        }
413    } else {
414        let content = resp.text().await?;
415        let entity: Option<DatasetsListError> = serde_json::from_str(&content).ok();
416        Err(Error::ResponseError(ResponseContent {
417            status,
418            content,
419            entity,
420        }))
421    }
422}