Skip to content

Commit 8a773bf

Browse files
authored
Cli updates + integration fix (#631)
* chore: cli updates * chore: no subprocess * chore: revert just use subprocess
1 parent 3d93c17 commit 8a773bf

File tree

2 files changed

+67
-33
lines changed

2 files changed

+67
-33
lines changed

src/judgeval/cli.py

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,111 @@
11
#!/usr/bin/env python3
22

3+
import os
4+
import subprocess
5+
import sys
36
import typer
47
from pathlib import Path
58
from dotenv import load_dotenv
69
from judgeval.logger import judgeval_logger
710
from judgeval import JudgmentClient
811
from judgeval.version import get_version
912
from judgeval.exceptions import JudgmentAPIError
13+
from judgeval.utils.project import _resolve_project_id
14+
from judgeval.utils.url import url_for
1015

1116
load_dotenv()
1217

1318
app = typer.Typer(
1419
no_args_is_help=True,
15-
rich_markup_mode=None,
16-
rich_help_panel=None,
1720
pretty_exceptions_enable=False,
1821
pretty_exceptions_show_locals=False,
1922
pretty_exceptions_short=False,
23+
rich_help_panel=None,
24+
rich_markup_mode=None,
25+
)
26+
27+
28+
@app.command(
29+
context_settings={"allow_extra_args": True, "ignore_unknown_options": True}
2030
)
31+
def load_otel_env(
32+
ctx: typer.Context,
33+
project_name: str = typer.Argument(help="Project name to send telemetry to"),
34+
api_key: str = typer.Option(None, envvar="JUDGMENT_API_KEY"),
35+
organization_id: str = typer.Option(None, envvar="JUDGMENT_ORG_ID"),
36+
):
37+
"""Run command with OpenTelemetry environment variables configured for Judgment."""
38+
if not api_key or not organization_id:
39+
raise typer.BadParameter("JUDGMENT_API_KEY and JUDGMENT_ORG_ID required")
40+
41+
project_id = _resolve_project_id(project_name, api_key, organization_id)
42+
if not project_id:
43+
raise typer.BadParameter(f"Project '{project_name}' not found")
44+
45+
if not ctx.args:
46+
raise typer.BadParameter(
47+
"No command provided. Usage: judgeval load_otel_env PROJECT_NAME -- COMMAND"
48+
)
49+
50+
env = os.environ.copy()
51+
env["OTEL_TRACES_EXPORTER"] = "otlp"
52+
env["OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"] = "http/protobuf"
53+
env["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"] = url_for("/otel/v1/traces")
54+
env["OTEL_EXPORTER_OTLP_HEADERS"] = (
55+
f"Authorization=Bearer {api_key},X-Organization-Id={organization_id},X-Project-Id={project_id}"
56+
)
57+
58+
result = subprocess.run(ctx.args, env=env)
59+
sys.exit(result.returncode)
2160

2261

23-
@app.command("upload_scorer")
62+
@app.command()
2463
def upload_scorer(
25-
scorer_file_path: str,
26-
requirements_file_path: str,
64+
scorer_file_path: str = typer.Argument(help="Path to scorer Python file"),
65+
requirements_file_path: str = typer.Argument(help="Path to requirements.txt file"),
2766
unique_name: str = typer.Option(
28-
None, help="Custom name for the scorer (auto-detected if not provided)"
67+
None, help="Custom scorer name (auto-detected if not provided)"
2968
),
3069
overwrite: bool = typer.Option(
31-
False,
32-
"--overwrite",
33-
"-o",
34-
help="Overwrite existing scorer if it already exists",
70+
False, "--overwrite", "-o", help="Overwrite if exists"
3571
),
72+
api_key: str = typer.Option(None, envvar="JUDGMENT_API_KEY"),
73+
organization_id: str = typer.Option(None, envvar="JUDGMENT_ORG_ID"),
3674
):
37-
# Validate file paths
38-
if not Path(scorer_file_path).exists():
39-
judgeval_logger.error(f"Scorer file not found: {scorer_file_path}")
40-
raise typer.Exit(1)
75+
"""Upload custom scorer to Judgment."""
76+
scorer_path = Path(scorer_file_path)
77+
requirements_path = Path(requirements_file_path)
78+
79+
if not scorer_path.exists():
80+
raise typer.BadParameter(f"Scorer file not found: {scorer_file_path}")
81+
if not requirements_path.exists():
82+
raise typer.BadParameter(
83+
f"Requirements file not found: {requirements_file_path}"
84+
)
4185

42-
if not Path(requirements_file_path).exists():
43-
judgeval_logger.error(f"Requirements file not found: {requirements_file_path}")
44-
raise typer.Exit(1)
86+
client = JudgmentClient(api_key=api_key, organization_id=organization_id)
4587

4688
try:
47-
client = JudgmentClient()
48-
4989
result = client.upload_custom_scorer(
5090
scorer_file_path=scorer_file_path,
5191
requirements_file_path=requirements_file_path,
5292
unique_name=unique_name,
5393
overwrite=overwrite,
5494
)
55-
5695
if not result:
57-
judgeval_logger.error("Failed to upload custom scorer")
58-
raise typer.Exit(1)
59-
96+
raise typer.Abort()
6097
judgeval_logger.info("Custom scorer uploaded successfully!")
61-
raise typer.Exit(0)
62-
except Exception as e:
63-
if isinstance(e, JudgmentAPIError) and e.status_code == 409:
64-
judgeval_logger.error(
65-
"Duplicate scorer detected. Use --overwrite flag to replace the existing scorer"
66-
)
98+
except JudgmentAPIError as e:
99+
if e.status_code == 409:
100+
judgeval_logger.error("Scorer exists. Use --overwrite to replace")
67101
raise typer.Exit(1)
68-
# Re-raise other exceptions
69102
raise
70103

71104

72105
@app.command()
73106
def version():
74-
"""Show version info"""
75-
judgeval_logger.info(f"Judgeval CLI v{get_version()}")
107+
"""Show Judgeval CLI version."""
108+
typer.echo(f"Judgeval CLI v{get_version()}")
76109

77110

78111
if __name__ == "__main__":

src/judgeval/integrations/openlit/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from judgeval.tracer import Tracer
33
from judgeval.logger import judgeval_logger
44
from judgeval.utils.url import url_for
5+
from judgeval.utils.project import _resolve_project_id
56

67

78
try:
@@ -27,7 +28,7 @@ def initialize(
2728
organization_id = tracer.organization_id
2829
project_name = tracer.project_name
2930

30-
project_id = Tracer._resolve_project_id(project_name, api_key, organization_id)
31+
project_id = _resolve_project_id(project_name, api_key, organization_id)
3132
if not project_id:
3233
judgeval_logger.warning(
3334
f"Project {project_name} not found. Please create it first at https://app.judgmentlabs.ai/org/{organization_id}/projects."

0 commit comments

Comments
 (0)