judgeval 0.7.1__py3-none-any.whl → 0.9.0__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.
- judgeval/__init__.py +139 -12
- judgeval/api/__init__.py +501 -0
- judgeval/api/api_types.py +344 -0
- judgeval/cli.py +2 -4
- judgeval/constants.py +10 -26
- judgeval/data/evaluation_run.py +49 -26
- judgeval/data/example.py +2 -2
- judgeval/data/judgment_types.py +266 -82
- judgeval/data/result.py +4 -5
- judgeval/data/scorer_data.py +4 -2
- judgeval/data/tool.py +2 -2
- judgeval/data/trace.py +7 -50
- judgeval/data/trace_run.py +7 -4
- judgeval/{dataset.py → dataset/__init__.py} +43 -28
- judgeval/env.py +67 -0
- judgeval/{run_evaluation.py → evaluation/__init__.py} +29 -95
- judgeval/exceptions.py +27 -0
- judgeval/integrations/langgraph/__init__.py +788 -0
- judgeval/judges/__init__.py +2 -2
- judgeval/judges/litellm_judge.py +75 -15
- judgeval/judges/together_judge.py +86 -18
- judgeval/judges/utils.py +7 -21
- judgeval/{common/logger.py → logger.py} +8 -6
- judgeval/scorers/__init__.py +0 -4
- judgeval/scorers/agent_scorer.py +3 -7
- judgeval/scorers/api_scorer.py +8 -13
- judgeval/scorers/base_scorer.py +52 -32
- judgeval/scorers/example_scorer.py +1 -3
- judgeval/scorers/judgeval_scorers/api_scorers/__init__.py +0 -14
- judgeval/scorers/judgeval_scorers/api_scorers/prompt_scorer.py +45 -20
- judgeval/scorers/judgeval_scorers/api_scorers/tool_dependency.py +2 -2
- judgeval/scorers/judgeval_scorers/api_scorers/tool_order.py +3 -3
- judgeval/scorers/score.py +21 -31
- judgeval/scorers/trace_api_scorer.py +5 -0
- judgeval/scorers/utils.py +1 -103
- judgeval/tracer/__init__.py +1075 -2
- judgeval/tracer/constants.py +1 -0
- judgeval/tracer/exporters/__init__.py +37 -0
- judgeval/tracer/exporters/s3.py +119 -0
- judgeval/tracer/exporters/store.py +43 -0
- judgeval/tracer/exporters/utils.py +32 -0
- judgeval/tracer/keys.py +67 -0
- judgeval/tracer/llm/__init__.py +1233 -0
- judgeval/{common/tracer → tracer/llm}/providers.py +5 -10
- judgeval/{local_eval_queue.py → tracer/local_eval_queue.py} +15 -10
- judgeval/tracer/managers.py +188 -0
- judgeval/tracer/processors/__init__.py +181 -0
- judgeval/tracer/utils.py +20 -0
- judgeval/trainer/__init__.py +5 -0
- judgeval/{common/trainer → trainer}/config.py +12 -9
- judgeval/{common/trainer → trainer}/console.py +2 -9
- judgeval/{common/trainer → trainer}/trainable_model.py +12 -7
- judgeval/{common/trainer → trainer}/trainer.py +119 -17
- judgeval/utils/async_utils.py +2 -3
- judgeval/utils/decorators.py +24 -0
- judgeval/utils/file_utils.py +37 -4
- judgeval/utils/guards.py +32 -0
- judgeval/utils/meta.py +14 -0
- judgeval/{common/api/json_encoder.py → utils/serialize.py} +7 -1
- judgeval/utils/testing.py +88 -0
- judgeval/utils/url.py +10 -0
- judgeval/{version_check.py → utils/version_check.py} +3 -3
- judgeval/version.py +5 -0
- judgeval/warnings.py +4 -0
- {judgeval-0.7.1.dist-info → judgeval-0.9.0.dist-info}/METADATA +12 -14
- judgeval-0.9.0.dist-info/RECORD +80 -0
- judgeval/clients.py +0 -35
- judgeval/common/__init__.py +0 -13
- judgeval/common/api/__init__.py +0 -3
- judgeval/common/api/api.py +0 -375
- judgeval/common/api/constants.py +0 -186
- judgeval/common/exceptions.py +0 -27
- judgeval/common/storage/__init__.py +0 -6
- judgeval/common/storage/s3_storage.py +0 -97
- judgeval/common/tracer/__init__.py +0 -31
- judgeval/common/tracer/constants.py +0 -22
- judgeval/common/tracer/core.py +0 -2427
- judgeval/common/tracer/otel_exporter.py +0 -108
- judgeval/common/tracer/otel_span_processor.py +0 -188
- judgeval/common/tracer/span_processor.py +0 -37
- judgeval/common/tracer/span_transformer.py +0 -207
- judgeval/common/tracer/trace_manager.py +0 -101
- judgeval/common/trainer/__init__.py +0 -5
- judgeval/common/utils.py +0 -948
- judgeval/integrations/langgraph.py +0 -844
- judgeval/judges/mixture_of_judges.py +0 -287
- judgeval/judgment_client.py +0 -267
- judgeval/rules.py +0 -521
- judgeval/scorers/judgeval_scorers/api_scorers/execution_order.py +0 -52
- judgeval/scorers/judgeval_scorers/api_scorers/hallucination.py +0 -28
- judgeval/utils/alerts.py +0 -93
- judgeval/utils/requests.py +0 -50
- judgeval-0.7.1.dist-info/RECORD +0 -82
- {judgeval-0.7.1.dist-info → judgeval-0.9.0.dist-info}/WHEEL +0 -0
- {judgeval-0.7.1.dist-info → judgeval-0.9.0.dist-info}/entry_points.txt +0 -0
- {judgeval-0.7.1.dist-info → judgeval-0.9.0.dist-info}/licenses/LICENSE.md +0 -0
judgeval/__init__.py
CHANGED
@@ -1,15 +1,142 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
from judgeval.
|
4
|
-
from judgeval.
|
5
|
-
from judgeval.
|
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
|
-
|
10
|
-
|
11
|
-
"
|
12
|
-
|
13
|
-
|
14
|
-
|
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,
|
43
|
+
eval_run_name: str,
|
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",)
|
judgeval/api/__init__.py
ADDED
@@ -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
|
+
]
|