Skip to content

Commit b227139

Browse files
author
Judgment Release Bot
committed
[Bump Minor Version] Release: Merge staging to main
2 parents 2f5909c + 9a773ff commit b227139

File tree

13 files changed

+187
-91
lines changed

13 files changed

+187
-91
lines changed

src/e2etests/conftest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ def project_name():
3939
def client(project_name: str) -> JudgmentClient:
4040
"""Create a single JudgmentClient instance for all tests."""
4141
# Setup
42+
if not API_KEY or not ORGANIZATION_ID:
43+
pytest.skip(
44+
"JUDGMENT_API_KEY or JUDGMENT_ORG_ID not set", allow_module_level=True
45+
)
4246
client = JudgmentClient(api_key=API_KEY, organization_id=ORGANIZATION_ID)
4347
create_project(project_name=project_name)
4448
yield client

src/e2etests/test_prompts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import uuid
66
import pytest
77
from judgeval import JudgmentClient
8-
from judgeval.prompts.prompt import Prompt
8+
from judgeval.prompt import Prompt
99
from judgeval.exceptions import JudgmentAPIError
1010

1111

src/judgeval/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ def upload_custom_scorer(
146146
requirements_text = f.read()
147147

148148
try:
149+
if not self.api_key or not self.organization_id:
150+
raise ValueError("Judgment API key and organization ID are required")
149151
client = JudgmentSyncClient(
150152
api_key=self.api_key,
151153
organization_id=self.organization_id,

src/judgeval/api/api_types.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# generated by datamodel-codegen:
22
# filename: .openapi.json
3-
# timestamp: 2025-10-21T01:37:42+00:00
3+
# timestamp: 2025-10-25T22:30:20+00:00
44

55
from __future__ import annotations
66
from typing import Any, Dict, List, Literal, Optional, TypedDict, Union
@@ -24,15 +24,6 @@ class DatasetsFetch(TypedDict):
2424
project_name: str
2525

2626

27-
class DatasetsTableRow(TypedDict):
28-
dataset_id: str
29-
name: str
30-
created_at: str
31-
kind: Literal["trace", "example"]
32-
entries: int
33-
creator: str
34-
35-
3627
class ProjectAdd(TypedDict):
3728
project_name: str
3829

@@ -67,13 +58,9 @@ class SavePromptScorerRequest(TypedDict):
6758
description: NotRequired[Optional[str]]
6859

6960

70-
class SavePromptScorerResponse(TypedDict):
71-
message: str
72-
name: str
73-
74-
7561
class FetchPromptScorersRequest(TypedDict):
7662
names: NotRequired[Optional[List[str]]]
63+
is_trace: NotRequired[Optional[bool]]
7764

7865

7966
class CustomScorerUploadPayload(TypedDict):
@@ -193,6 +180,9 @@ class UsageInfo(TypedDict):
193180

194181

195182
class PromptScorer(TypedDict):
183+
id: str
184+
user_id: str
185+
organization_id: str
196186
name: str
197187
prompt: str
198188
threshold: float
@@ -202,6 +192,7 @@ class PromptScorer(TypedDict):
202192
created_at: NotRequired[Optional[str]]
203193
updated_at: NotRequired[Optional[str]]
204194
is_trace: NotRequired[Optional[bool]]
195+
is_bucket_rubric: NotRequired[Optional[bool]]
205196

206197

207198
class PromptCommitInfo(TypedDict):
@@ -292,6 +283,7 @@ class TraceEvaluationRun(TypedDict):
292283
created_at: NotRequired[str]
293284
trace_and_span_ids: List[TraceAndSpanId]
294285
is_offline: NotRequired[bool]
286+
is_bucket_run: NotRequired[bool]
295287

296288

297289
class DatasetInsertExamples(TypedDict):
@@ -300,6 +292,15 @@ class DatasetInsertExamples(TypedDict):
300292
project_name: str
301293

302294

295+
class DatasetInfo(TypedDict):
296+
dataset_id: str
297+
name: str
298+
created_at: str
299+
kind: DatasetKind
300+
entries: int
301+
creator: str
302+
303+
303304
class DatasetCreate(TypedDict):
304305
name: str
305306
dataset_kind: DatasetKind
@@ -308,6 +309,10 @@ class DatasetCreate(TypedDict):
308309
overwrite: bool
309310

310311

312+
class SavePromptScorerResponse(TypedDict):
313+
scorer_response: PromptScorer
314+
315+
311316
class FetchPromptScorersResponse(TypedDict):
312317
scorers: List[PromptScorer]
313318

@@ -342,6 +347,7 @@ class OtelTraceListItem(TypedDict):
342347
llm_cost: NotRequired[Optional[float]]
343348
error: NotRequired[str]
344349
scores: NotRequired[List[OtelSpanListItemScores]]
350+
rules_invoked: NotRequired[List[str]]
345351
customer_id: NotRequired[Optional[str]]
346352
input: NotRequired[Optional[str]]
347353
output: NotRequired[Optional[str]]

src/judgeval/data/judgment_types.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# generated by datamodel-codegen:
22
# filename: .openapi.json
3-
# timestamp: 2025-10-21T01:37:41+00:00
3+
# timestamp: 2025-10-25T22:30:19+00:00
44

55
from __future__ import annotations
66
from typing import Annotated, Any, Dict, List, Optional, Union
@@ -26,20 +26,6 @@ class DatasetsFetch(BaseModel):
2626
project_name: Annotated[str, Field(title="Project Name")]
2727

2828

29-
class Kind(Enum):
30-
trace = "trace"
31-
example = "example"
32-
33-
34-
class DatasetsTableRow(BaseModel):
35-
dataset_id: Annotated[str, Field(title="Dataset Id")]
36-
name: Annotated[str, Field(title="Name")]
37-
created_at: Annotated[str, Field(title="Created At")]
38-
kind: Annotated[Kind, Field(title="Kind")]
39-
entries: Annotated[int, Field(title="Entries")]
40-
creator: Annotated[str, Field(title="Creator")]
41-
42-
4329
class ProjectAdd(BaseModel):
4430
project_name: Annotated[str, Field(title="Project Name")]
4531

@@ -74,13 +60,9 @@ class SavePromptScorerRequest(BaseModel):
7460
description: Annotated[Optional[str], Field(title="Description")] = None
7561

7662

77-
class SavePromptScorerResponse(BaseModel):
78-
message: Annotated[str, Field(title="Message")]
79-
name: Annotated[str, Field(title="Name")]
80-
81-
8263
class FetchPromptScorersRequest(BaseModel):
8364
names: Annotated[Optional[List[str]], Field(title="Names")] = None
65+
is_trace: Annotated[Optional[bool], Field(title="Is Trace")] = None
8466

8567

8668
class CustomScorerUploadPayload(BaseModel):
@@ -211,6 +193,9 @@ class DatasetKind(Enum):
211193

212194

213195
class PromptScorer(BaseModel):
196+
id: Annotated[str, Field(title="Id")]
197+
user_id: Annotated[str, Field(title="User Id")]
198+
organization_id: Annotated[str, Field(title="Organization Id")]
214199
name: Annotated[str, Field(title="Name")]
215200
prompt: Annotated[str, Field(title="Prompt")]
216201
threshold: Annotated[float, Field(title="Threshold")]
@@ -220,6 +205,7 @@ class PromptScorer(BaseModel):
220205
created_at: Annotated[Optional[AwareDatetime], Field(title="Created At")] = None
221206
updated_at: Annotated[Optional[AwareDatetime], Field(title="Updated At")] = None
222207
is_trace: Annotated[Optional[bool], Field(title="Is Trace")] = False
208+
is_bucket_rubric: Annotated[Optional[bool], Field(title="Is Bucket Rubric")] = None
223209

224210

225211
class PromptCommitInfo(BaseModel):
@@ -326,6 +312,7 @@ class TraceEvaluationRun(BaseModel):
326312
List[TraceAndSpanId], Field(title="Trace And Span Ids")
327313
]
328314
is_offline: Annotated[Optional[bool], Field(title="Is Offline")] = False
315+
is_bucket_run: Annotated[Optional[bool], Field(title="Is Bucket Run")] = False
329316

330317

331318
class DatasetInsertExamples(BaseModel):
@@ -334,6 +321,15 @@ class DatasetInsertExamples(BaseModel):
334321
project_name: Annotated[str, Field(title="Project Name")]
335322

336323

324+
class DatasetInfo(BaseModel):
325+
dataset_id: Annotated[str, Field(title="Dataset Id")]
326+
name: Annotated[str, Field(title="Name")]
327+
created_at: Annotated[str, Field(title="Created At")]
328+
kind: DatasetKind
329+
entries: Annotated[int, Field(title="Entries")]
330+
creator: Annotated[str, Field(title="Creator")]
331+
332+
337333
class DatasetCreate(BaseModel):
338334
name: Annotated[str, Field(title="Name")]
339335
dataset_kind: DatasetKind
@@ -342,6 +338,10 @@ class DatasetCreate(BaseModel):
342338
overwrite: Annotated[bool, Field(title="Overwrite")]
343339

344340

341+
class SavePromptScorerResponse(BaseModel):
342+
scorer_response: PromptScorer
343+
344+
345345
class FetchPromptScorersResponse(BaseModel):
346346
scorers: Annotated[List[PromptScorer], Field(title="Scorers")]
347347

@@ -380,6 +380,7 @@ class OtelTraceListItem(BaseModel):
380380
scores: Annotated[
381381
Optional[List[OtelSpanListItemScores]], Field(title="Scores")
382382
] = []
383+
rules_invoked: Annotated[Optional[List[str]], Field(title="Rules Invoked")] = []
383384
customer_id: Annotated[Optional[str], Field(title="Customer Id")] = None
384385
input: Annotated[Optional[str], Field(title="Input")] = None
385386
output: Annotated[Optional[str], Field(title="Output")] = None

src/judgeval/dataset/__init__.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,17 @@ class Dataset:
3232
dataset_kind: DatasetKind = DatasetKind.example
3333
examples: Optional[List[Example]] = None
3434
traces: Optional[List[Trace]] = None
35-
judgment_api_key: str = JUDGMENT_API_KEY or ""
36-
organization_id: str = JUDGMENT_ORG_ID or ""
35+
judgment_api_key: str | None = JUDGMENT_API_KEY
36+
organization_id: str | None = JUDGMENT_ORG_ID
3737

3838
@classmethod
3939
def get(
4040
cls,
4141
name: str,
4242
project_name: str,
4343
):
44+
if not cls.judgment_api_key or not cls.organization_id:
45+
raise ValueError("Judgment API key and organization ID are required")
4446
client = JudgmentSyncClient(cls.judgment_api_key, cls.organization_id)
4547
dataset = client.datasets_pull_for_judgeval(
4648
{
@@ -102,6 +104,8 @@ def create(
102104
examples: List[Example] = [],
103105
overwrite: bool = False,
104106
):
107+
if not cls.judgment_api_key or not cls.organization_id:
108+
raise ValueError("Judgment API key and organization ID are required")
105109
if not examples:
106110
examples = []
107111

@@ -125,6 +129,8 @@ def create(
125129

126130
@classmethod
127131
def list(cls, project_name: str):
132+
if not cls.judgment_api_key or not cls.organization_id:
133+
raise ValueError("Judgment API key and organization ID are required")
128134
client = JudgmentSyncClient(cls.judgment_api_key, cls.organization_id)
129135
datasets = client.datasets_pull_all_for_judgeval({"project_name": project_name})
130136

@@ -173,6 +179,9 @@ def add_examples(self, examples: List[Example]) -> None:
173179
if not isinstance(examples, list):
174180
raise TypeError("examples must be a list")
175181

182+
if not self.judgment_api_key or not self.organization_id:
183+
raise ValueError("Judgment API key and organization ID are required")
184+
176185
client = JudgmentSyncClient(self.judgment_api_key, self.organization_id)
177186
client.datasets_insert_examples_for_judgeval(
178187
{

src/judgeval/env.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,8 @@ def optional_env_var(var_name: str, default: str | None = None) -> str | None:
1919
return os.getenv(var_name, default)
2020

2121

22-
def required_env_var(var_name: str) -> str:
23-
value = os.getenv(var_name)
24-
if value is None:
25-
raise EnvironmentError(
26-
f"Environment variable '{var_name}' is required but not set."
27-
)
28-
return value
29-
30-
31-
JUDGMENT_API_KEY = required_env_var("JUDGMENT_API_KEY")
32-
JUDGMENT_ORG_ID = required_env_var("JUDGMENT_ORG_ID")
22+
JUDGMENT_API_KEY = optional_env_var("JUDGMENT_API_KEY")
23+
JUDGMENT_ORG_ID = optional_env_var("JUDGMENT_ORG_ID")
3324
JUDGMENT_API_URL = optional_env_var("JUDGMENT_API_URL", "https://api.judgmentlabs.ai")
3425

3526
JUDGMENT_DEFAULT_GPT_MODEL = optional_env_var("JUDGMENT_DEFAULT_GPT_MODEL", "gpt-5")

src/judgeval/evaluation/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ def _poll_evaluation_until_complete(
112112

113113
poll_count = 0
114114
exception_count = 0
115+
if not JUDGMENT_API_KEY or not JUDGMENT_ORG_ID:
116+
raise ValueError("Judgment API key and organization ID are required")
115117
api_client = JudgmentSyncClient(JUDGMENT_API_KEY, JUDGMENT_ORG_ID)
116118
while poll_count < max_poll_count:
117119
poll_count += 1
@@ -222,6 +224,8 @@ def run_eval(
222224
)
223225
t.start()
224226
try:
227+
if not JUDGMENT_API_KEY or not JUDGMENT_ORG_ID:
228+
raise ValueError("Judgment API key and organization ID are required")
225229
api_client = JudgmentSyncClient(JUDGMENT_API_KEY, JUDGMENT_ORG_ID)
226230
response = api_client.add_to_run_eval_queue_examples(
227231
evaluation_run.model_dump(warnings=False) # type: ignore

0 commit comments

Comments
 (0)