Skip to main content

langfuse_client_base/apis/
evaluators_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 [`evaluators_create`]
17#[derive(Debug, Clone, Serialize, Deserialize)]
18#[serde(untagged)]
19pub enum EvaluatorsCreateError {
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    Status412(models::PublicApiError),
26    Status429(models::PublicApiError),
27    Status500(models::PublicApiError),
28    UnknownValue(serde_json::Value),
29}
30
31/// struct for typed errors of method [`evaluators_delete`]
32#[derive(Debug, Clone, Serialize, Deserialize)]
33#[serde(untagged)]
34pub enum EvaluatorsDeleteError {
35    Status400(serde_json::Value),
36    Status401(serde_json::Value),
37    Status403(serde_json::Value),
38    Status404(serde_json::Value),
39    Status405(serde_json::Value),
40    Status429(models::PublicApiError),
41    Status500(models::PublicApiError),
42    UnknownValue(serde_json::Value),
43}
44
45/// struct for typed errors of method [`evaluators_get`]
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(untagged)]
48pub enum EvaluatorsGetError {
49    Status400(serde_json::Value),
50    Status401(serde_json::Value),
51    Status403(serde_json::Value),
52    Status404(serde_json::Value),
53    Status405(serde_json::Value),
54    Status429(models::PublicApiError),
55    Status500(models::PublicApiError),
56    UnknownValue(serde_json::Value),
57}
58
59/// struct for typed errors of method [`evaluators_list`]
60#[derive(Debug, Clone, Serialize, Deserialize)]
61#[serde(untagged)]
62pub enum EvaluatorsListError {
63    Status400(serde_json::Value),
64    Status401(serde_json::Value),
65    Status403(serde_json::Value),
66    Status404(serde_json::Value),
67    Status405(serde_json::Value),
68    Status429(models::PublicApiError),
69    Status500(models::PublicApiError),
70    UnknownValue(serde_json::Value),
71}
72
73/// struct for typed errors of method [`evaluators_list_versions`]
74#[derive(Debug, Clone, Serialize, Deserialize)]
75#[serde(untagged)]
76pub enum EvaluatorsListVersionsError {
77    Status400(serde_json::Value),
78    Status401(serde_json::Value),
79    Status403(serde_json::Value),
80    Status404(serde_json::Value),
81    Status405(serde_json::Value),
82    Status429(models::PublicApiError),
83    Status500(models::PublicApiError),
84    UnknownValue(serde_json::Value),
85}
86
87/// struct for typed errors of method [`evaluators_update`]
88#[derive(Debug, Clone, Serialize, Deserialize)]
89#[serde(untagged)]
90pub enum EvaluatorsUpdateError {
91    Status400(serde_json::Value),
92    Status401(serde_json::Value),
93    Status403(serde_json::Value),
94    Status404(serde_json::Value),
95    Status405(serde_json::Value),
96    Status409(models::PublicApiError),
97    Status412(models::PublicApiError),
98    Status429(models::PublicApiError),
99    Status500(models::PublicApiError),
100    UnknownValue(serde_json::Value),
101}
102
103/// Create an evaluator in the authenticated project.  An evaluator defines **how** Langfuse should score data. LLM-as-a-judge evaluators define a prompt, expected structured output, and optional model configuration. Code evaluators define source code and a runtime language.  This always creates a new evaluator with version `1`. Names are not identifiers and do not need to be unique.
104#[bon::builder]
105pub async fn evaluators_create(
106    configuration: &configuration::Configuration,
107    create_evaluator_request: models::CreateEvaluatorRequest,
108) -> Result<models::Evaluator, Error<EvaluatorsCreateError>> {
109    // add a prefix to parameters to efficiently prevent name collisions
110    let p_body_create_evaluator_request = create_evaluator_request;
111
112    let uri_str = format!("{}/api/public/v2/evaluators", configuration.base_path);
113    let mut req_builder = configuration
114        .client
115        .request(reqwest::Method::POST, &uri_str);
116
117    if let Some(ref user_agent) = configuration.user_agent {
118        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
119    }
120    if let Some(ref auth_conf) = configuration.basic_auth {
121        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
122    };
123    req_builder = req_builder.json(&p_body_create_evaluator_request);
124
125    let req = req_builder.build()?;
126    let resp = configuration.client.execute(req).await?;
127
128    let status = resp.status();
129    let content_type = resp
130        .headers()
131        .get("content-type")
132        .and_then(|v| v.to_str().ok())
133        .unwrap_or("application/octet-stream");
134    let content_type = super::ContentType::from(content_type);
135
136    if !status.is_client_error() && !status.is_server_error() {
137        let content = resp.text().await?;
138        match content_type {
139            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
140            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Evaluator`"))),
141            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::Evaluator`")))),
142        }
143    } else {
144        let content = resp.text().await?;
145        let entity: Option<EvaluatorsCreateError> = serde_json::from_str(&content).ok();
146        Err(Error::ResponseError(ResponseContent {
147            status,
148            content,
149            entity,
150        }))
151    }
152}
153
154/// Delete an evaluator and all of its stored versions.  Associated evaluation-rule assignments are also removed. Scores already produced by the evaluator are preserved.
155#[bon::builder]
156pub async fn evaluators_delete(
157    configuration: &configuration::Configuration,
158    evaluator_id: &str,
159) -> Result<models::DeletedEvaluator, Error<EvaluatorsDeleteError>> {
160    // add a prefix to parameters to efficiently prevent name collisions
161    let p_path_evaluator_id = evaluator_id;
162
163    let uri_str = format!(
164        "{}/api/public/v2/evaluators/{evaluatorId}",
165        configuration.base_path,
166        evaluatorId = crate::apis::urlencode(p_path_evaluator_id)
167    );
168    let mut req_builder = configuration
169        .client
170        .request(reqwest::Method::DELETE, &uri_str);
171
172    if let Some(ref user_agent) = configuration.user_agent {
173        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
174    }
175    if let Some(ref auth_conf) = configuration.basic_auth {
176        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
177    };
178
179    let req = req_builder.build()?;
180    let resp = configuration.client.execute(req).await?;
181
182    let status = resp.status();
183    let content_type = resp
184        .headers()
185        .get("content-type")
186        .and_then(|v| v.to_str().ok())
187        .unwrap_or("application/octet-stream");
188    let content_type = super::ContentType::from(content_type);
189
190    if !status.is_client_error() && !status.is_server_error() {
191        let content = resp.text().await?;
192        match content_type {
193            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
194            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DeletedEvaluator`"))),
195            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::DeletedEvaluator`")))),
196        }
197    } else {
198        let content = resp.text().await?;
199        let entity: Option<EvaluatorsDeleteError> = serde_json::from_str(&content).ok();
200        Err(Error::ResponseError(ResponseContent {
201            status,
202            content,
203            entity,
204        }))
205    }
206}
207
208/// Get one evaluator by its stable identifier.  The response includes the evaluator's latest definition and version metadata flattened into the evaluator object, plus associated evaluation rules. Use the version-history endpoint when older definitions are needed.
209#[bon::builder]
210pub async fn evaluators_get(
211    configuration: &configuration::Configuration,
212    evaluator_id: &str,
213) -> Result<models::Evaluator, Error<EvaluatorsGetError>> {
214    // add a prefix to parameters to efficiently prevent name collisions
215    let p_path_evaluator_id = evaluator_id;
216
217    let uri_str = format!(
218        "{}/api/public/v2/evaluators/{evaluatorId}",
219        configuration.base_path,
220        evaluatorId = crate::apis::urlencode(p_path_evaluator_id)
221    );
222    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
223
224    if let Some(ref user_agent) = configuration.user_agent {
225        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
226    }
227    if let Some(ref auth_conf) = configuration.basic_auth {
228        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
229    };
230
231    let req = req_builder.build()?;
232    let resp = configuration.client.execute(req).await?;
233
234    let status = resp.status();
235    let content_type = resp
236        .headers()
237        .get("content-type")
238        .and_then(|v| v.to_str().ok())
239        .unwrap_or("application/octet-stream");
240    let content_type = super::ContentType::from(content_type);
241
242    if !status.is_client_error() && !status.is_server_error() {
243        let content = resp.text().await?;
244        match content_type {
245            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
246            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Evaluator`"))),
247            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::Evaluator`")))),
248        }
249    } else {
250        let content = resp.text().await?;
251        let entity: Option<EvaluatorsGetError> = serde_json::from_str(&content).ok();
252        Err(Error::ResponseError(ResponseContent {
253            status,
254            content,
255            entity,
256        }))
257    }
258}
259
260/// List evaluators in newest-first creation order.  Every evaluator includes its latest definition and version metadata flattened into the evaluator object, plus associated evaluation rules. Treat the cursor as opaque and return it unchanged.
261#[bon::builder]
262pub async fn evaluators_list(
263    configuration: &configuration::Configuration,
264    limit: Option<i32>,
265    cursor: Option<&str>,
266) -> Result<models::EvaluatorsPage, Error<EvaluatorsListError>> {
267    // add a prefix to parameters to efficiently prevent name collisions
268    let p_query_limit = limit;
269    let p_query_cursor = cursor;
270
271    let uri_str = format!("{}/api/public/v2/evaluators", configuration.base_path);
272    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
273
274    if let Some(ref param_value) = p_query_limit {
275        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
276    }
277    if let Some(ref param_value) = p_query_cursor {
278        req_builder = req_builder.query(&[("cursor", &param_value.to_string())]);
279    }
280    if let Some(ref user_agent) = configuration.user_agent {
281        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
282    }
283    if let Some(ref auth_conf) = configuration.basic_auth {
284        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
285    };
286
287    let req = req_builder.build()?;
288    let resp = configuration.client.execute(req).await?;
289
290    let status = resp.status();
291    let content_type = resp
292        .headers()
293        .get("content-type")
294        .and_then(|v| v.to_str().ok())
295        .unwrap_or("application/octet-stream");
296    let content_type = super::ContentType::from(content_type);
297
298    if !status.is_client_error() && !status.is_server_error() {
299        let content = resp.text().await?;
300        match content_type {
301            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
302            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::EvaluatorsPage`"))),
303            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::EvaluatorsPage`")))),
304        }
305    } else {
306        let content = resp.text().await?;
307        let entity: Option<EvaluatorsListError> = serde_json::from_str(&content).ok();
308        Err(Error::ResponseError(ResponseContent {
309            status,
310            content,
311            entity,
312        }))
313    }
314}
315
316/// List an evaluator's version history in newest-first order.  This endpoint is intended for history and audit use cases. Ordinary clients can use the flattened `version` and definition fields on the evaluator response.
317#[bon::builder]
318pub async fn evaluators_list_versions(
319    configuration: &configuration::Configuration,
320    evaluator_id: &str,
321    limit: Option<i32>,
322    cursor: Option<&str>,
323) -> Result<models::EvaluatorVersionsPage, Error<EvaluatorsListVersionsError>> {
324    // add a prefix to parameters to efficiently prevent name collisions
325    let p_path_evaluator_id = evaluator_id;
326    let p_query_limit = limit;
327    let p_query_cursor = cursor;
328
329    let uri_str = format!(
330        "{}/api/public/v2/evaluators/{evaluatorId}/versions",
331        configuration.base_path,
332        evaluatorId = crate::apis::urlencode(p_path_evaluator_id)
333    );
334    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
335
336    if let Some(ref param_value) = p_query_limit {
337        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
338    }
339    if let Some(ref param_value) = p_query_cursor {
340        req_builder = req_builder.query(&[("cursor", &param_value.to_string())]);
341    }
342    if let Some(ref user_agent) = configuration.user_agent {
343        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
344    }
345    if let Some(ref auth_conf) = configuration.basic_auth {
346        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
347    };
348
349    let req = req_builder.build()?;
350    let resp = configuration.client.execute(req).await?;
351
352    let status = resp.status();
353    let content_type = resp
354        .headers()
355        .get("content-type")
356        .and_then(|v| v.to_str().ok())
357        .unwrap_or("application/octet-stream");
358    let content_type = super::ContentType::from(content_type);
359
360    if !status.is_client_error() && !status.is_server_error() {
361        let content = resp.text().await?;
362        match content_type {
363            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
364            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::EvaluatorVersionsPage`"))),
365            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::EvaluatorVersionsPage`")))),
366        }
367    } else {
368        let content = resp.text().await?;
369        let entity: Option<EvaluatorsListVersionsError> = serde_json::from_str(&content).ok();
370        Err(Error::ResponseError(ResponseContent {
371            status,
372            content,
373            entity,
374        }))
375    }
376}
377
378/// Update an evaluator by its stable identifier.  Provide only the top-level fields to change. Metadata-only changes do not create a version. Evaluator type cannot change.  Definition fields are flattened into the request. To replace a definition, include `type` and every definition field for that type. Definition fields are replaced as a complete unit rather than merged. For LLM-as-a-judge evaluators, omitting or setting `modelConfig` to `null` selects the project's default evaluation model.  Replacing a definition automatically returns an evaluator paused by an invalid or missing model configuration to `active`, while preserving its id and evaluation-rule assignments. Pauses caused by provider authentication, billing, connectivity, account state, or an unknown legacy reason remain paused until the explicit reactivation check succeeds.
379#[bon::builder]
380pub async fn evaluators_update(
381    configuration: &configuration::Configuration,
382    evaluator_id: &str,
383    update_evaluator_request: models::UpdateEvaluatorRequest,
384) -> Result<models::Evaluator, Error<EvaluatorsUpdateError>> {
385    // add a prefix to parameters to efficiently prevent name collisions
386    let p_path_evaluator_id = evaluator_id;
387    let p_body_update_evaluator_request = update_evaluator_request;
388
389    let uri_str = format!(
390        "{}/api/public/v2/evaluators/{evaluatorId}",
391        configuration.base_path,
392        evaluatorId = crate::apis::urlencode(p_path_evaluator_id)
393    );
394    let mut req_builder = configuration
395        .client
396        .request(reqwest::Method::PATCH, &uri_str);
397
398    if let Some(ref user_agent) = configuration.user_agent {
399        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
400    }
401    if let Some(ref auth_conf) = configuration.basic_auth {
402        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
403    };
404    req_builder = req_builder.json(&p_body_update_evaluator_request);
405
406    let req = req_builder.build()?;
407    let resp = configuration.client.execute(req).await?;
408
409    let status = resp.status();
410    let content_type = resp
411        .headers()
412        .get("content-type")
413        .and_then(|v| v.to_str().ok())
414        .unwrap_or("application/octet-stream");
415    let content_type = super::ContentType::from(content_type);
416
417    if !status.is_client_error() && !status.is_server_error() {
418        let content = resp.text().await?;
419        match content_type {
420            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
421            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Evaluator`"))),
422            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::Evaluator`")))),
423        }
424    } else {
425        let content = resp.text().await?;
426        let entity: Option<EvaluatorsUpdateError> = serde_json::from_str(&content).ok();
427        Err(Error::ResponseError(ResponseContent {
428            status,
429            content,
430            entity,
431        }))
432    }
433}