judgeval 0.8.0__py3-none-any.whl → 0.9.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. judgeval/__init__.py +139 -12
  2. judgeval/api/__init__.py +501 -0
  3. judgeval/api/api_types.py +344 -0
  4. judgeval/cli.py +2 -4
  5. judgeval/constants.py +10 -26
  6. judgeval/data/evaluation_run.py +49 -26
  7. judgeval/data/example.py +2 -2
  8. judgeval/data/judgment_types.py +266 -82
  9. judgeval/data/result.py +4 -5
  10. judgeval/data/scorer_data.py +4 -2
  11. judgeval/data/tool.py +2 -2
  12. judgeval/data/trace.py +7 -50
  13. judgeval/data/trace_run.py +7 -4
  14. judgeval/{dataset.py → dataset/__init__.py} +43 -28
  15. judgeval/env.py +67 -0
  16. judgeval/{run_evaluation.py → evaluation/__init__.py} +29 -95
  17. judgeval/exceptions.py +27 -0
  18. judgeval/integrations/langgraph/__init__.py +788 -0
  19. judgeval/judges/__init__.py +2 -2
  20. judgeval/judges/litellm_judge.py +75 -15
  21. judgeval/judges/together_judge.py +86 -18
  22. judgeval/judges/utils.py +7 -21
  23. judgeval/{common/logger.py → logger.py} +8 -6
  24. judgeval/scorers/__init__.py +0 -4
  25. judgeval/scorers/agent_scorer.py +3 -7
  26. judgeval/scorers/api_scorer.py +8 -13
  27. judgeval/scorers/base_scorer.py +52 -32
  28. judgeval/scorers/example_scorer.py +1 -3
  29. judgeval/scorers/judgeval_scorers/api_scorers/__init__.py +0 -14
  30. judgeval/scorers/judgeval_scorers/api_scorers/prompt_scorer.py +45 -20
  31. judgeval/scorers/judgeval_scorers/api_scorers/tool_dependency.py +2 -2
  32. judgeval/scorers/judgeval_scorers/api_scorers/tool_order.py +3 -3
  33. judgeval/scorers/score.py +21 -31
  34. judgeval/scorers/trace_api_scorer.py +5 -0
  35. judgeval/scorers/utils.py +1 -103
  36. judgeval/tracer/__init__.py +1075 -2
  37. judgeval/tracer/constants.py +1 -0
  38. judgeval/tracer/exporters/__init__.py +37 -0
  39. judgeval/tracer/exporters/s3.py +119 -0
  40. judgeval/tracer/exporters/store.py +43 -0
  41. judgeval/tracer/exporters/utils.py +32 -0
  42. judgeval/tracer/keys.py +67 -0
  43. judgeval/tracer/llm/__init__.py +1233 -0
  44. judgeval/{common/tracer → tracer/llm}/providers.py +5 -10
  45. judgeval/{local_eval_queue.py → tracer/local_eval_queue.py} +15 -10
  46. judgeval/tracer/managers.py +188 -0
  47. judgeval/tracer/processors/__init__.py +181 -0
  48. judgeval/tracer/utils.py +20 -0
  49. judgeval/trainer/__init__.py +5 -0
  50. judgeval/{common/trainer → trainer}/config.py +12 -9
  51. judgeval/{common/trainer → trainer}/console.py +2 -9
  52. judgeval/{common/trainer → trainer}/trainable_model.py +12 -7
  53. judgeval/{common/trainer → trainer}/trainer.py +119 -17
  54. judgeval/utils/async_utils.py +2 -3
  55. judgeval/utils/decorators.py +24 -0
  56. judgeval/utils/file_utils.py +37 -4
  57. judgeval/utils/guards.py +32 -0
  58. judgeval/utils/meta.py +14 -0
  59. judgeval/{common/api/json_encoder.py → utils/serialize.py} +7 -1
  60. judgeval/utils/testing.py +88 -0
  61. judgeval/utils/url.py +10 -0
  62. judgeval/{version_check.py → utils/version_check.py} +3 -3
  63. judgeval/version.py +5 -0
  64. judgeval/warnings.py +4 -0
  65. {judgeval-0.8.0.dist-info → judgeval-0.9.1.dist-info}/METADATA +12 -14
  66. judgeval-0.9.1.dist-info/RECORD +80 -0
  67. judgeval/clients.py +0 -35
  68. judgeval/common/__init__.py +0 -13
  69. judgeval/common/api/__init__.py +0 -3
  70. judgeval/common/api/api.py +0 -375
  71. judgeval/common/api/constants.py +0 -186
  72. judgeval/common/exceptions.py +0 -27
  73. judgeval/common/storage/__init__.py +0 -6
  74. judgeval/common/storage/s3_storage.py +0 -97
  75. judgeval/common/tracer/__init__.py +0 -31
  76. judgeval/common/tracer/constants.py +0 -22
  77. judgeval/common/tracer/core.py +0 -2427
  78. judgeval/common/tracer/otel_exporter.py +0 -108
  79. judgeval/common/tracer/otel_span_processor.py +0 -188
  80. judgeval/common/tracer/span_processor.py +0 -37
  81. judgeval/common/tracer/span_transformer.py +0 -207
  82. judgeval/common/tracer/trace_manager.py +0 -101
  83. judgeval/common/trainer/__init__.py +0 -5
  84. judgeval/common/utils.py +0 -948
  85. judgeval/integrations/langgraph.py +0 -844
  86. judgeval/judges/mixture_of_judges.py +0 -287
  87. judgeval/judgment_client.py +0 -267
  88. judgeval/rules.py +0 -521
  89. judgeval/scorers/judgeval_scorers/api_scorers/execution_order.py +0 -52
  90. judgeval/scorers/judgeval_scorers/api_scorers/hallucination.py +0 -28
  91. judgeval/utils/alerts.py +0 -93
  92. judgeval/utils/requests.py +0 -50
  93. judgeval-0.8.0.dist-info/RECORD +0 -82
  94. {judgeval-0.8.0.dist-info → judgeval-0.9.1.dist-info}/WHEEL +0 -0
  95. {judgeval-0.8.0.dist-info → judgeval-0.9.1.dist-info}/entry_points.txt +0 -0
  96. {judgeval-0.8.0.dist-info → judgeval-0.9.1.dist-info}/licenses/LICENSE.md +0 -0
judgeval/__init__.py CHANGED
@@ -1,15 +1,142 @@
1
- # Import key components that should be publicly accessible
2
- from judgeval.clients import client, together_client
3
- from judgeval.judgment_client import JudgmentClient
4
- from judgeval.version_check import check_latest_version
5
- from judgeval.local_eval_queue import LocalEvaluationQueue
1
+ from __future__ import annotations
2
+
3
+ from judgeval.data.result import ScoringResult
4
+ from judgeval.evaluation import run_eval
5
+ from judgeval.data.evaluation_run import ExampleEvaluationRun
6
+
7
+
8
+ from typing import List, Optional, Union
9
+ from judgeval.scorers import BaseScorer, APIScorerConfig
10
+ from judgeval.data.example import Example
11
+ from judgeval.logger import judgeval_logger
12
+ from judgeval.env import JUDGMENT_API_KEY, JUDGMENT_DEFAULT_GPT_MODEL, JUDGMENT_ORG_ID
13
+ from judgeval.utils.meta import SingletonMeta
14
+ from judgeval.exceptions import JudgmentRuntimeError, JudgmentTestError
15
+ from judgeval.api import JudgmentSyncClient
16
+ from judgeval.utils.file_utils import extract_scorer_name
17
+ from judgeval.utils.guards import expect_api_key, expect_organization_id
18
+ from judgeval.utils.version_check import check_latest_version
19
+ from judgeval.utils.testing import assert_test_results
6
20
 
7
21
  check_latest_version()
8
22
 
9
- __all__ = [
10
- # Clients
11
- "client",
12
- "together_client",
13
- "JudgmentClient",
14
- "LocalEvaluationQueue",
15
- ]
23
+
24
+ class JudgmentClient(metaclass=SingletonMeta):
25
+ __slots__ = ("api_key", "organization_id")
26
+
27
+ def __init__(
28
+ self,
29
+ api_key: Optional[str] = None,
30
+ organization_id: Optional[str] = None,
31
+ ):
32
+ _api_key = api_key or JUDGMENT_API_KEY
33
+ _organization_id = organization_id or JUDGMENT_ORG_ID
34
+
35
+ self.api_key = expect_api_key(_api_key)
36
+ self.organization_id = expect_organization_id(_organization_id)
37
+
38
+ def run_evaluation(
39
+ self,
40
+ examples: List[Example],
41
+ scorers: List[Union[APIScorerConfig, BaseScorer]],
42
+ project_name: str = "default_project",
43
+ eval_run_name: str = "default_eval_run",
44
+ model: str = JUDGMENT_DEFAULT_GPT_MODEL,
45
+ assert_test: bool = False,
46
+ ) -> List[ScoringResult]:
47
+ try:
48
+ eval = ExampleEvaluationRun(
49
+ project_name=project_name,
50
+ eval_name=eval_run_name,
51
+ examples=examples,
52
+ scorers=scorers,
53
+ model=model,
54
+ organization_id=self.organization_id,
55
+ )
56
+
57
+ results = run_eval(eval, self.api_key)
58
+ if assert_test:
59
+ assert_test_results(results)
60
+
61
+ return results
62
+
63
+ except JudgmentTestError as e:
64
+ raise JudgmentTestError(e)
65
+ except ValueError as e:
66
+ raise ValueError(
67
+ f"Please check your EvaluationRun object, one or more fields are invalid: \n{e}"
68
+ )
69
+ except Exception as e:
70
+ raise JudgmentRuntimeError(
71
+ f"An unexpected error occured during evaluation: {e}"
72
+ ) from e
73
+
74
+ def upload_custom_scorer(
75
+ self,
76
+ scorer_file_path: str,
77
+ requirements_file_path: Optional[str] = None,
78
+ unique_name: Optional[str] = None,
79
+ ) -> bool:
80
+ """
81
+ Upload custom ExampleScorer from files to backend.
82
+
83
+ Args:
84
+ scorer_file_path: Path to Python file containing CustomScorer class
85
+ requirements_file_path: Optional path to requirements.txt
86
+ unique_name: Optional unique identifier (auto-detected from scorer.name if not provided)
87
+
88
+ Returns:
89
+ bool: True if upload successful
90
+
91
+ Raises:
92
+ ValueError: If scorer file is invalid
93
+ FileNotFoundError: If scorer file doesn't exist
94
+ """
95
+ import os
96
+
97
+ if not os.path.exists(scorer_file_path):
98
+ raise FileNotFoundError(f"Scorer file not found: {scorer_file_path}")
99
+
100
+ # Auto-detect scorer name if not provided
101
+ if unique_name is None:
102
+ unique_name = extract_scorer_name(scorer_file_path)
103
+ judgeval_logger.info(f"Auto-detected scorer name: '{unique_name}'")
104
+
105
+ # Read scorer code
106
+ with open(scorer_file_path, "r") as f:
107
+ scorer_code = f.read()
108
+
109
+ # Read requirements (optional)
110
+ requirements_text = ""
111
+ if requirements_file_path and os.path.exists(requirements_file_path):
112
+ with open(requirements_file_path, "r") as f:
113
+ requirements_text = f.read()
114
+
115
+ try:
116
+ client = JudgmentSyncClient(
117
+ api_key=self.api_key,
118
+ organization_id=self.organization_id,
119
+ )
120
+ response = client.upload_custom_scorer(
121
+ payload={
122
+ "scorer_name": unique_name,
123
+ "scorer_code": scorer_code,
124
+ "requirements_text": requirements_text,
125
+ }
126
+ )
127
+
128
+ if response.get("status") == "success":
129
+ judgeval_logger.info(
130
+ f"Successfully uploaded custom scorer: {unique_name}"
131
+ )
132
+ return True
133
+ else:
134
+ judgeval_logger.error(f"Failed to upload custom scorer: {unique_name}")
135
+ return False
136
+
137
+ except Exception as e:
138
+ judgeval_logger.error(f"Error uploading custom scorer: {e}")
139
+ raise
140
+
141
+
142
+ __all__ = ("JudgmentClient",)
@@ -0,0 +1,501 @@
1
+ from typing import Dict, Any, Mapping, Literal, Optional
2
+ import httpx
3
+ from httpx import Response
4
+ from judgeval.exceptions import JudgmentAPIError
5
+ from judgeval.utils.url import url_for
6
+ from judgeval.utils.serialize import json_encoder
7
+ from judgeval.api.api_types import *
8
+
9
+
10
+ def _headers(api_key: str, organization_id: str) -> Mapping[str, str]:
11
+ return {
12
+ "Content-Type": "application/json",
13
+ "Authorization": f"Bearer {api_key}",
14
+ "X-Organization-Id": organization_id,
15
+ }
16
+
17
+
18
+ def _handle_response(r: Response) -> Any:
19
+ if r.status_code >= 400:
20
+ try:
21
+ detail = r.json().get("detail", "")
22
+ except Exception:
23
+ detail = r.text
24
+ raise JudgmentAPIError(r.status_code, detail, r)
25
+ return r.json()
26
+
27
+
28
+ class JudgmentSyncClient:
29
+ __slots__ = ("api_key", "organization_id", "client")
30
+
31
+ def __init__(self, api_key: str, organization_id: str):
32
+ self.api_key = api_key
33
+ self.organization_id = organization_id
34
+ self.client = httpx.Client(timeout=30)
35
+
36
+ def _request(
37
+ self,
38
+ method: Literal["POST", "PATCH", "GET", "DELETE"],
39
+ url: str,
40
+ payload: Any,
41
+ params: Optional[Dict[str, Any]] = None,
42
+ ) -> Any:
43
+ if method == "GET":
44
+ r = self.client.request(
45
+ method,
46
+ url,
47
+ params=payload if params is None else params,
48
+ headers=_headers(self.api_key, self.organization_id),
49
+ )
50
+ else:
51
+ r = self.client.request(
52
+ method,
53
+ url,
54
+ json=json_encoder(payload),
55
+ params=params,
56
+ headers=_headers(self.api_key, self.organization_id),
57
+ )
58
+ return _handle_response(r)
59
+
60
+ def add_to_run_eval_queue_examples(self, payload: ExampleEvaluationRun) -> Any:
61
+ return self._request(
62
+ "POST",
63
+ url_for("/add_to_run_eval_queue/examples"),
64
+ payload,
65
+ )
66
+
67
+ def add_to_run_eval_queue_traces(self, payload: TraceEvaluationRun) -> Any:
68
+ return self._request(
69
+ "POST",
70
+ url_for("/add_to_run_eval_queue/traces"),
71
+ payload,
72
+ )
73
+
74
+ def evaluate_trace(self, payload: TraceRun) -> Any:
75
+ return self._request(
76
+ "POST",
77
+ url_for("/evaluate_trace/"),
78
+ payload,
79
+ )
80
+
81
+ def evaluate_examples(
82
+ self, payload: ExampleEvaluationRun, stream: Optional[str] = None
83
+ ) -> Any:
84
+ query_params = {}
85
+ if stream is not None:
86
+ query_params["stream"] = stream
87
+ return self._request(
88
+ "POST",
89
+ url_for("/evaluate/examples"),
90
+ payload,
91
+ params=query_params,
92
+ )
93
+
94
+ def evaluate_traces(
95
+ self, payload: TraceEvaluationRun, stream: Optional[str] = None
96
+ ) -> Any:
97
+ query_params = {}
98
+ if stream is not None:
99
+ query_params["stream"] = stream
100
+ return self._request(
101
+ "POST",
102
+ url_for("/evaluate/traces"),
103
+ payload,
104
+ params=query_params,
105
+ )
106
+
107
+ def log_eval_results(self, payload: EvalResults) -> Any:
108
+ return self._request(
109
+ "POST",
110
+ url_for("/log_eval_results/"),
111
+ payload,
112
+ )
113
+
114
+ def fetch_experiment_run(self, payload: EvalResultsFetch) -> Any:
115
+ return self._request(
116
+ "POST",
117
+ url_for("/fetch_experiment_run/"),
118
+ payload,
119
+ )
120
+
121
+ def get_evaluation_status(self, experiment_run_id: str, project_name: str) -> Any:
122
+ query_params = {}
123
+ query_params["experiment_run_id"] = experiment_run_id
124
+ query_params["project_name"] = project_name
125
+ return self._request(
126
+ "GET",
127
+ url_for("/get_evaluation_status/"),
128
+ query_params,
129
+ )
130
+
131
+ def datasets_insert_examples(self, payload: DatasetInsertExamples) -> Any:
132
+ return self._request(
133
+ "POST",
134
+ url_for("/datasets/insert_examples/"),
135
+ payload,
136
+ )
137
+
138
+ def datasets_pull_for_judgeval(self, payload: DatasetFetch) -> Any:
139
+ return self._request(
140
+ "POST",
141
+ url_for("/datasets/pull_for_judgeval/"),
142
+ payload,
143
+ )
144
+
145
+ def datasets_push(self, payload: DatasetPush) -> Any:
146
+ return self._request(
147
+ "POST",
148
+ url_for("/datasets/push/"),
149
+ payload,
150
+ )
151
+
152
+ def traces_upsert(self, payload: TraceSave) -> Any:
153
+ return self._request(
154
+ "POST",
155
+ url_for("/traces/upsert/"),
156
+ payload,
157
+ )
158
+
159
+ def traces_fetch(self, payload: TraceFetch) -> Any:
160
+ return self._request(
161
+ "POST",
162
+ url_for("/traces/fetch/"),
163
+ payload,
164
+ )
165
+
166
+ def traces_add_to_dataset(self, payload: TraceAddToDataset) -> Any:
167
+ return self._request(
168
+ "POST",
169
+ url_for("/traces/add_to_dataset/"),
170
+ payload,
171
+ )
172
+
173
+ def traces_spans_batch(self, payload: SpansBatchRequest) -> Any:
174
+ return self._request(
175
+ "POST",
176
+ url_for("/traces/spans/batch/"),
177
+ payload,
178
+ )
179
+
180
+ def traces_evaluation_runs_batch(self, payload: EvaluationRunsBatchRequest) -> Any:
181
+ return self._request(
182
+ "POST",
183
+ url_for("/traces/evaluation_runs/batch/"),
184
+ payload,
185
+ )
186
+
187
+ def projects_add(self, payload: ProjectAdd) -> ProjectAddResponse:
188
+ return self._request(
189
+ "POST",
190
+ url_for("/projects/add/"),
191
+ payload,
192
+ )
193
+
194
+ def projects_delete_from_judgeval(
195
+ self, payload: ProjectDeleteFromJudgevalResponse
196
+ ) -> ProjectDeleteResponse:
197
+ return self._request(
198
+ "DELETE",
199
+ url_for("/projects/delete_from_judgeval/"),
200
+ payload,
201
+ )
202
+
203
+ def scorer_exists(self, payload: ScorerExistsRequest) -> ScorerExistsResponse:
204
+ return self._request(
205
+ "POST",
206
+ url_for("/scorer_exists/"),
207
+ payload,
208
+ )
209
+
210
+ def save_scorer(self, payload: SavePromptScorerRequest) -> SavePromptScorerResponse:
211
+ return self._request(
212
+ "POST",
213
+ url_for("/save_scorer/"),
214
+ payload,
215
+ )
216
+
217
+ def fetch_scorer(
218
+ self, payload: FetchPromptScorerRequest
219
+ ) -> FetchPromptScorerResponse:
220
+ return self._request(
221
+ "POST",
222
+ url_for("/fetch_scorer/"),
223
+ payload,
224
+ )
225
+
226
+ def upload_custom_scorer(
227
+ self, payload: CustomScorerUploadPayload
228
+ ) -> CustomScorerTemplateResponse:
229
+ return self._request(
230
+ "POST",
231
+ url_for("/upload_custom_scorer/"),
232
+ payload,
233
+ )
234
+
235
+ def projects_resolve(
236
+ self, payload: ResolveProjectNameRequest
237
+ ) -> ResolveProjectNameResponse:
238
+ return self._request(
239
+ "POST",
240
+ url_for("/projects/resolve/"),
241
+ payload,
242
+ )
243
+
244
+ def e2e_fetch_trace(self, payload: TraceIdRequest) -> Any:
245
+ return self._request(
246
+ "POST",
247
+ url_for("/e2e_fetch_trace/"),
248
+ payload,
249
+ )
250
+
251
+ def e2e_fetch_span_score(self, payload: SpanScoreRequest) -> Any:
252
+ return self._request(
253
+ "POST",
254
+ url_for("/e2e_fetch_span_score/"),
255
+ payload,
256
+ )
257
+
258
+
259
+ class JudgmentAsyncClient:
260
+ __slots__ = ("api_key", "organization_id", "client")
261
+
262
+ def __init__(self, api_key: str, organization_id: str):
263
+ self.api_key = api_key
264
+ self.organization_id = organization_id
265
+ self.client = httpx.AsyncClient(timeout=30)
266
+
267
+ async def _request(
268
+ self,
269
+ method: Literal["POST", "PATCH", "GET", "DELETE"],
270
+ url: str,
271
+ payload: Any,
272
+ params: Optional[Dict[str, Any]] = None,
273
+ ) -> Any:
274
+ if method == "GET":
275
+ r = self.client.request(
276
+ method,
277
+ url,
278
+ params=payload if params is None else params,
279
+ headers=_headers(self.api_key, self.organization_id),
280
+ )
281
+ else:
282
+ r = self.client.request(
283
+ method,
284
+ url,
285
+ json=json_encoder(payload),
286
+ params=params,
287
+ headers=_headers(self.api_key, self.organization_id),
288
+ )
289
+ return _handle_response(await r)
290
+
291
+ async def add_to_run_eval_queue_examples(
292
+ self, payload: ExampleEvaluationRun
293
+ ) -> Any:
294
+ return await self._request(
295
+ "POST",
296
+ url_for("/add_to_run_eval_queue/examples"),
297
+ payload,
298
+ )
299
+
300
+ async def add_to_run_eval_queue_traces(self, payload: TraceEvaluationRun) -> Any:
301
+ return await self._request(
302
+ "POST",
303
+ url_for("/add_to_run_eval_queue/traces"),
304
+ payload,
305
+ )
306
+
307
+ async def evaluate_trace(self, payload: TraceRun) -> Any:
308
+ return await self._request(
309
+ "POST",
310
+ url_for("/evaluate_trace/"),
311
+ payload,
312
+ )
313
+
314
+ async def evaluate_examples(
315
+ self, payload: ExampleEvaluationRun, stream: Optional[str] = None
316
+ ) -> Any:
317
+ query_params = {}
318
+ if stream is not None:
319
+ query_params["stream"] = stream
320
+ return await self._request(
321
+ "POST",
322
+ url_for("/evaluate/examples"),
323
+ payload,
324
+ params=query_params,
325
+ )
326
+
327
+ async def evaluate_traces(
328
+ self, payload: TraceEvaluationRun, stream: Optional[str] = None
329
+ ) -> Any:
330
+ query_params = {}
331
+ if stream is not None:
332
+ query_params["stream"] = stream
333
+ return await self._request(
334
+ "POST",
335
+ url_for("/evaluate/traces"),
336
+ payload,
337
+ params=query_params,
338
+ )
339
+
340
+ async def log_eval_results(self, payload: EvalResults) -> Any:
341
+ return await self._request(
342
+ "POST",
343
+ url_for("/log_eval_results/"),
344
+ payload,
345
+ )
346
+
347
+ async def fetch_experiment_run(self, payload: EvalResultsFetch) -> Any:
348
+ return await self._request(
349
+ "POST",
350
+ url_for("/fetch_experiment_run/"),
351
+ payload,
352
+ )
353
+
354
+ async def get_evaluation_status(
355
+ self, experiment_run_id: str, project_name: str
356
+ ) -> Any:
357
+ query_params = {}
358
+ query_params["experiment_run_id"] = experiment_run_id
359
+ query_params["project_name"] = project_name
360
+ return await self._request(
361
+ "GET",
362
+ url_for("/get_evaluation_status/"),
363
+ query_params,
364
+ )
365
+
366
+ async def datasets_insert_examples(self, payload: DatasetInsertExamples) -> Any:
367
+ return await self._request(
368
+ "POST",
369
+ url_for("/datasets/insert_examples/"),
370
+ payload,
371
+ )
372
+
373
+ async def datasets_pull_for_judgeval(self, payload: DatasetFetch) -> Any:
374
+ return await self._request(
375
+ "POST",
376
+ url_for("/datasets/pull_for_judgeval/"),
377
+ payload,
378
+ )
379
+
380
+ async def datasets_push(self, payload: DatasetPush) -> Any:
381
+ return await self._request(
382
+ "POST",
383
+ url_for("/datasets/push/"),
384
+ payload,
385
+ )
386
+
387
+ async def traces_upsert(self, payload: TraceSave) -> Any:
388
+ return await self._request(
389
+ "POST",
390
+ url_for("/traces/upsert/"),
391
+ payload,
392
+ )
393
+
394
+ async def traces_fetch(self, payload: TraceFetch) -> Any:
395
+ return await self._request(
396
+ "POST",
397
+ url_for("/traces/fetch/"),
398
+ payload,
399
+ )
400
+
401
+ async def traces_add_to_dataset(self, payload: TraceAddToDataset) -> Any:
402
+ return await self._request(
403
+ "POST",
404
+ url_for("/traces/add_to_dataset/"),
405
+ payload,
406
+ )
407
+
408
+ async def traces_spans_batch(self, payload: SpansBatchRequest) -> Any:
409
+ return await self._request(
410
+ "POST",
411
+ url_for("/traces/spans/batch/"),
412
+ payload,
413
+ )
414
+
415
+ async def traces_evaluation_runs_batch(
416
+ self, payload: EvaluationRunsBatchRequest
417
+ ) -> Any:
418
+ return await self._request(
419
+ "POST",
420
+ url_for("/traces/evaluation_runs/batch/"),
421
+ payload,
422
+ )
423
+
424
+ async def projects_add(self, payload: ProjectAdd) -> ProjectAddResponse:
425
+ return await self._request(
426
+ "POST",
427
+ url_for("/projects/add/"),
428
+ payload,
429
+ )
430
+
431
+ async def projects_delete_from_judgeval(
432
+ self, payload: ProjectDeleteFromJudgevalResponse
433
+ ) -> ProjectDeleteResponse:
434
+ return await self._request(
435
+ "DELETE",
436
+ url_for("/projects/delete_from_judgeval/"),
437
+ payload,
438
+ )
439
+
440
+ async def scorer_exists(self, payload: ScorerExistsRequest) -> ScorerExistsResponse:
441
+ return await self._request(
442
+ "POST",
443
+ url_for("/scorer_exists/"),
444
+ payload,
445
+ )
446
+
447
+ async def save_scorer(
448
+ self, payload: SavePromptScorerRequest
449
+ ) -> SavePromptScorerResponse:
450
+ return await self._request(
451
+ "POST",
452
+ url_for("/save_scorer/"),
453
+ payload,
454
+ )
455
+
456
+ async def fetch_scorer(
457
+ self, payload: FetchPromptScorerRequest
458
+ ) -> FetchPromptScorerResponse:
459
+ return await self._request(
460
+ "POST",
461
+ url_for("/fetch_scorer/"),
462
+ payload,
463
+ )
464
+
465
+ async def upload_custom_scorer(
466
+ self, payload: CustomScorerUploadPayload
467
+ ) -> CustomScorerTemplateResponse:
468
+ return await self._request(
469
+ "POST",
470
+ url_for("/upload_custom_scorer/"),
471
+ payload,
472
+ )
473
+
474
+ async def projects_resolve(
475
+ self, payload: ResolveProjectNameRequest
476
+ ) -> ResolveProjectNameResponse:
477
+ return await self._request(
478
+ "POST",
479
+ url_for("/projects/resolve/"),
480
+ payload,
481
+ )
482
+
483
+ async def e2e_fetch_trace(self, payload: TraceIdRequest) -> Any:
484
+ return await self._request(
485
+ "POST",
486
+ url_for("/e2e_fetch_trace/"),
487
+ payload,
488
+ )
489
+
490
+ async def e2e_fetch_span_score(self, payload: SpanScoreRequest) -> Any:
491
+ return await self._request(
492
+ "POST",
493
+ url_for("/e2e_fetch_span_score/"),
494
+ payload,
495
+ )
496
+
497
+
498
+ __all__ = [
499
+ "JudgmentSyncClient",
500
+ "JudgmentAsyncClient",
501
+ ]