nemo-evaluator-launcher 0.1.0rc9__tar.gz → 0.1.2__tar.gz

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.

Potentially problematic release.


This version of nemo-evaluator-launcher might be problematic. Click here for more details.

Files changed (63) hide show
  1. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/PKG-INFO +1 -1
  2. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/cli/export.py +3 -2
  3. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/cli/kill.py +5 -3
  4. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/cli/ls_runs.py +6 -5
  5. nemo_evaluator_launcher-0.1.2/src/nemo_evaluator_launcher/cli/ls_tasks.py +136 -0
  6. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/cli/main.py +6 -5
  7. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/cli/run.py +6 -4
  8. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/cli/status.py +5 -3
  9. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/lepton/job_helpers.py +15 -11
  10. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/package_info.py +2 -2
  11. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher.egg-info/PKG-INFO +1 -1
  12. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher.egg-info/SOURCES.txt +0 -1
  13. nemo_evaluator_launcher-0.1.0rc9/src/nemo_evaluator_launcher/cli/info.py +0 -117
  14. nemo_evaluator_launcher-0.1.0rc9/src/nemo_evaluator_launcher/cli/ls_tasks.py +0 -34
  15. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/LICENSE +0 -0
  16. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/README.md +0 -0
  17. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/pyproject.toml +0 -0
  18. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/setup.cfg +0 -0
  19. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/__init__.py +0 -0
  20. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/api/__init__.py +0 -0
  21. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/api/functional.py +0 -0
  22. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/api/types.py +0 -0
  23. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/api/utils.py +0 -0
  24. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/cli/__init__.py +0 -0
  25. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/cli/version.py +0 -0
  26. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/common/__init__.py +0 -0
  27. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/common/execdb.py +0 -0
  28. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/common/helpers.py +0 -0
  29. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/common/logging_utils.py +0 -0
  30. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/common/mapping.py +0 -0
  31. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/__init__.py +0 -0
  32. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/default.yaml +0 -0
  33. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/deployment/nim.yaml +0 -0
  34. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/deployment/none.yaml +0 -0
  35. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/deployment/sglang.yaml +0 -0
  36. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/deployment/vllm.yaml +0 -0
  37. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/execution/lepton/default.yaml +0 -0
  38. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/execution/local.yaml +0 -0
  39. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/configs/execution/slurm/default.yaml +0 -0
  40. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/__init__.py +0 -0
  41. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/base.py +0 -0
  42. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/lepton/__init__.py +0 -0
  43. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/lepton/deployment_helpers.py +0 -0
  44. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/lepton/executor.py +0 -0
  45. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/local/__init__.py +0 -0
  46. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/local/executor.py +0 -0
  47. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/local/run.template.sh +0 -0
  48. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/registry.py +0 -0
  49. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/slurm/__init__.py +0 -0
  50. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/executors/slurm/executor.py +0 -0
  51. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/exporters/__init__.py +0 -0
  52. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/exporters/base.py +0 -0
  53. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/exporters/gsheets.py +0 -0
  54. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/exporters/local.py +0 -0
  55. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/exporters/mlflow.py +0 -0
  56. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/exporters/registry.py +0 -0
  57. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/exporters/utils.py +0 -0
  58. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/exporters/wandb.py +0 -0
  59. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher/resources/mapping.toml +0 -0
  60. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher.egg-info/dependency_links.txt +0 -0
  61. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher.egg-info/entry_points.txt +0 -0
  62. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher.egg-info/requires.txt +0 -0
  63. {nemo_evaluator_launcher-0.1.0rc9 → nemo_evaluator_launcher-0.1.2}/src/nemo_evaluator_launcher.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nemo-evaluator-launcher
3
- Version: 0.1.0rc9
3
+ Version: 0.1.2
4
4
  Summary: Launcher for the evaluations provided by NeMo Evaluator containers with different runtime backends
5
5
  Author: NVIDIA
6
6
  Author-email: nemo-toolkit@nvidia.com
@@ -20,8 +20,6 @@ from typing import Any, List, Optional
20
20
 
21
21
  from simple_parsing import field
22
22
 
23
- from nemo_evaluator_launcher.api.functional import export_results
24
-
25
23
 
26
24
  @dataclass
27
25
  class ExportCmd:
@@ -77,6 +75,9 @@ class ExportCmd:
77
75
 
78
76
  def execute(self) -> None:
79
77
  """Execute export."""
78
+ # Import heavy dependencies only when needed
79
+ from nemo_evaluator_launcher.api.functional import export_results
80
+
80
81
  config: dict[str, Any] = {
81
82
  "copy_logs": self.copy_logs,
82
83
  "only_required": self.only_required,
@@ -13,13 +13,10 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- import json
17
16
  from dataclasses import dataclass
18
17
 
19
18
  from simple_parsing import field
20
19
 
21
- from nemo_evaluator_launcher.api.functional import kill_job_or_invocation
22
-
23
20
 
24
21
  @dataclass
25
22
  class Cmd:
@@ -34,6 +31,11 @@ class Cmd:
34
31
 
35
32
  def execute(self) -> None:
36
33
  """Execute the kill command."""
34
+ # Import heavy dependencies only when needed
35
+ import json
36
+
37
+ from nemo_evaluator_launcher.api.functional import kill_job_or_invocation
38
+
37
39
  result = kill_job_or_invocation(self.id)
38
40
  # Output as JSON
39
41
  print(json.dumps(result, indent=2))
@@ -20,11 +20,6 @@ from typing import Optional
20
20
 
21
21
  from simple_parsing import field
22
22
 
23
- from nemo_evaluator_launcher.api.functional import (
24
- get_invocation_benchmarks,
25
- list_all_invocations_summary,
26
- )
27
-
28
23
 
29
24
  @dataclass
30
25
  class Cmd:
@@ -41,6 +36,12 @@ class Cmd:
41
36
  )
42
37
 
43
38
  def execute(self) -> None:
39
+ # Import heavy dependencies only when needed
40
+ from nemo_evaluator_launcher.api.functional import (
41
+ get_invocation_benchmarks,
42
+ list_all_invocations_summary,
43
+ )
44
+
44
45
  rows = list_all_invocations_summary()
45
46
 
46
47
  if self.executor:
@@ -0,0 +1,136 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ from collections import defaultdict
17
+ from dataclasses import dataclass
18
+
19
+ from simple_parsing import field
20
+
21
+
22
+ @dataclass
23
+ class Cmd:
24
+ """List command configuration."""
25
+
26
+ json: bool = field(
27
+ default=False,
28
+ action="store_true",
29
+ help="Print output as JSON instead of table format",
30
+ )
31
+
32
+ def execute(self) -> None:
33
+ # Import heavy dependencies only when needed
34
+ import json
35
+
36
+ from nemo_evaluator_launcher.api.functional import get_tasks_list
37
+
38
+ # TODO(dfridman): modify `get_tasks_list` to return a list of dicts in the first place
39
+ data = get_tasks_list()
40
+ headers = ["task", "endpoint_type", "harness", "container"]
41
+ supported_benchmarks = []
42
+ for task_data in data:
43
+ assert len(task_data) == len(headers)
44
+ supported_benchmarks.append(dict(zip(headers, task_data)))
45
+
46
+ if self.json:
47
+ print(json.dumps({"tasks": supported_benchmarks}, indent=2))
48
+ else:
49
+ self._print_table(supported_benchmarks)
50
+
51
+ def _print_table(self, tasks: list[dict]) -> None:
52
+ """Print tasks grouped by harness and container in table format."""
53
+ if not tasks:
54
+ print("No tasks found.")
55
+ return
56
+
57
+ # Group tasks by harness and container
58
+ grouped = defaultdict(lambda: defaultdict(list))
59
+ for task in tasks:
60
+ harness = task["harness"]
61
+ container = task["container"]
62
+ grouped[harness][container].append(task)
63
+
64
+ # Print grouped tables
65
+ for i, (harness, containers) in enumerate(grouped.items()):
66
+ if i > 0:
67
+ print() # Extra spacing between harnesses
68
+
69
+ for j, (container, container_tasks) in enumerate(containers.items()):
70
+ if j > 0:
71
+ print() # Spacing between containers
72
+
73
+ # Prepare task table first to get column widths
74
+ task_headers = ["task", "endpoint_type"]
75
+ rows = []
76
+ for task in container_tasks:
77
+ rows.append([task["task"], task["endpoint_type"]])
78
+
79
+ # Sort tasks alphabetically for better readability
80
+ rows.sort(key=lambda x: x[0])
81
+
82
+ # Calculate column widths with some padding
83
+ widths = [
84
+ max(len(task_headers[i]), max(len(str(row[i])) for row in rows)) + 2
85
+ for i in range(len(task_headers))
86
+ ]
87
+
88
+ # Calculate minimum table width based on task columns
89
+ min_table_width = sum(widths) + len(widths) + 1
90
+
91
+ # Calculate required width for header content
92
+ harness_line = f"harness: {harness}"
93
+ container_line = f"container: {container}"
94
+ header_content_width = (
95
+ max(len(harness_line), len(container_line)) + 4
96
+ ) # +4 for "| " and " |"
97
+
98
+ # Use the larger of the two widths
99
+ table_width = max(min_table_width, header_content_width)
100
+
101
+ # Print combined header with harness and container info
102
+ print("=" * table_width)
103
+ print(f"{harness_line}")
104
+ print(f"{container_line}")
105
+
106
+ # Adjust column widths to fill the full table width
107
+ available_width = table_width
108
+ # Give more space to the first column (task names can be long)
109
+ adjusted_widths = [
110
+ max(
111
+ widths[0], available_width * 2 // 3
112
+ ), # 2/3 of available width for task
113
+ 0, # Will be calculated as remainder
114
+ ]
115
+ adjusted_widths[1] = (
116
+ available_width - adjusted_widths[0]
117
+ ) # Remainder for endpoint_type
118
+
119
+ # Print task table header separator
120
+ print(" " * table_width)
121
+ header_row = f"{task_headers[0]:<{adjusted_widths[0]}}{task_headers[1]:<{adjusted_widths[1]}}"
122
+ print(header_row)
123
+ print("-" * table_width)
124
+
125
+ # Print task rows
126
+ for row in rows:
127
+ data_row = f"{str(row[0]):<{adjusted_widths[0]}}{str(row[1]):<{adjusted_widths[1]}}"
128
+ print(data_row)
129
+
130
+ print("-" * table_width)
131
+ # Show task count
132
+ task_count = len(rows)
133
+ print(f" {task_count} task{'s' if task_count != 1 else ''} available")
134
+ print("=" * table_width)
135
+
136
+ print()
@@ -70,6 +70,9 @@ def create_parser() -> ArgumentParser:
70
70
  ls_parser = subparsers.add_parser(
71
71
  "ls", help="List resources", description="List tasks or runs"
72
72
  )
73
+ # Add arguments from `ls tasks` so that they work with `ls` as default alias
74
+ ls_parser.add_arguments(ls_tasks.Cmd, dest="tasks_alias")
75
+
73
76
  ls_sub = ls_parser.add_subparsers(dest="ls_command", required=False)
74
77
 
75
78
  # ls tasks (default)
@@ -126,12 +129,10 @@ def main() -> None:
126
129
  # Dispatch nested ls subcommands
127
130
  if args.ls_command is None or args.ls_command == "tasks":
128
131
  # Default to tasks when no subcommand specified
129
- if hasattr(args, "tasks"):
130
- args.tasks.execute()
132
+ if hasattr(args, "tasks_alias"):
133
+ args.tasks_alias.execute()
131
134
  else:
132
- # Create default tasks command if not specified
133
- tasks_cmd = ls_tasks.Cmd()
134
- tasks_cmd.execute()
135
+ args.tasks.execute()
135
136
  elif args.ls_command == "runs":
136
137
  args.runs.execute()
137
138
  elif args.command == "export":
@@ -17,12 +17,8 @@ import pathlib
17
17
  import time
18
18
  from dataclasses import dataclass
19
19
 
20
- import yaml
21
- from omegaconf import OmegaConf
22
20
  from simple_parsing import field
23
21
 
24
- from nemo_evaluator_launcher.api.functional import RunConfig, run_eval
25
-
26
22
 
27
23
  @dataclass
28
24
  class Cmd:
@@ -65,6 +61,12 @@ class Cmd:
65
61
  )
66
62
 
67
63
  def execute(self) -> None:
64
+ # Import heavy dependencies only when needed
65
+ import yaml
66
+ from omegaconf import OmegaConf
67
+
68
+ from nemo_evaluator_launcher.api.functional import RunConfig, run_eval
69
+
68
70
  # Load configuration either from Hydra or from a run config file
69
71
  if self.run_config_file:
70
72
  # Validate that run config file is not used with other config options
@@ -13,13 +13,10 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- import json
17
16
  from dataclasses import dataclass
18
17
 
19
18
  from simple_parsing import field
20
19
 
21
- from nemo_evaluator_launcher.api.functional import get_status
22
-
23
20
 
24
21
  @dataclass
25
22
  class Cmd:
@@ -36,6 +33,11 @@ class Cmd:
36
33
  )
37
34
 
38
35
  def execute(self) -> None:
36
+ # Import heavy dependencies only when needed
37
+ import json
38
+
39
+ from nemo_evaluator_launcher.api.functional import get_status
40
+
39
41
  res = get_status(self.job_ids)
40
42
  if self.json:
41
43
  # Remove progress field from JSON output as it's a WIP feature
@@ -23,13 +23,6 @@ import subprocess
23
23
  import time
24
24
  from typing import Any, List, Union
25
25
 
26
- from leptonai.api.v1.types.affinity import LeptonResourceAffinity
27
- from leptonai.api.v1.types.common import LeptonVisibility, Metadata
28
- from leptonai.api.v1.types.deployment import EnvVar, LeptonContainer, Mount
29
- from leptonai.api.v1.types.job import LeptonJob, LeptonJobUserSpec
30
-
31
- # Import lepton dependencies
32
- from leptonai.api.v2.client import APIClient
33
26
  from omegaconf import DictConfig
34
27
 
35
28
  from nemo_evaluator_launcher.common.logging_utils import logger
@@ -92,6 +85,18 @@ def _create_lepton_job_api(
92
85
  ) -> tuple[bool, str]:
93
86
  """Create Lepton job using API client (preferred method)."""
94
87
  try:
88
+ # Import leptonai dependencies locally
89
+ from leptonai.api.v1.types.affinity import LeptonResourceAffinity
90
+ from leptonai.api.v1.types.common import LeptonVisibility, Metadata
91
+ from leptonai.api.v1.types.deployment import (
92
+ EnvValue,
93
+ EnvVar,
94
+ LeptonContainer,
95
+ Mount,
96
+ )
97
+ from leptonai.api.v1.types.job import LeptonJob, LeptonJobUserSpec
98
+ from leptonai.api.v2.client import APIClient
99
+
95
100
  client = APIClient()
96
101
 
97
102
  # Prepare environment variables (support both direct values and secret references)
@@ -99,12 +104,8 @@ def _create_lepton_job_api(
99
104
  if env_vars:
100
105
  for key, value in env_vars.items():
101
106
  # Handle both regular dicts and OmegaConf objects
102
- from omegaconf import DictConfig
103
-
104
107
  if isinstance(value, (dict, DictConfig)) and "value_from" in value:
105
108
  # Secret reference: {value_from: {secret_name_ref: "secret_name"}}
106
- from leptonai.api.v1.types.deployment import EnvValue
107
-
108
109
  # Convert OmegaConf to dict if needed
109
110
  value_dict = dict(value) if isinstance(value, DictConfig) else value
110
111
  env_var = EnvVar(
@@ -203,6 +204,9 @@ def get_lepton_job_status(job_name_or_id: str) -> dict[Any, Any] | None:
203
204
  def _get_lepton_job_status_api(job_name_or_id: str) -> dict[Any, Any] | None:
204
205
  """Get job status using API client (preferred method)."""
205
206
  try:
207
+ # Import leptonai dependencies locally
208
+ from leptonai.api.v2.client import APIClient
209
+
206
210
  client = APIClient()
207
211
 
208
212
  # Try to get job by ID first, then by name
@@ -16,8 +16,8 @@
16
16
  # Below is the _next_ version that will be published, not the currently published one.
17
17
  MAJOR = 0
18
18
  MINOR = 1
19
- PATCH = 0
20
- PRE_RELEASE = "rc9"
19
+ PATCH = 2
20
+ PRE_RELEASE = ""
21
21
 
22
22
  # Use the following formatting: (major, minor, patch, pre-release)
23
23
  VERSION = (MAJOR, MINOR, PATCH, PRE_RELEASE)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nemo-evaluator-launcher
3
- Version: 0.1.0rc9
3
+ Version: 0.1.2
4
4
  Summary: Launcher for the evaluations provided by NeMo Evaluator containers with different runtime backends
5
5
  Author: NVIDIA
6
6
  Author-email: nemo-toolkit@nvidia.com
@@ -15,7 +15,6 @@ src/nemo_evaluator_launcher/api/types.py
15
15
  src/nemo_evaluator_launcher/api/utils.py
16
16
  src/nemo_evaluator_launcher/cli/__init__.py
17
17
  src/nemo_evaluator_launcher/cli/export.py
18
- src/nemo_evaluator_launcher/cli/info.py
19
18
  src/nemo_evaluator_launcher/cli/kill.py
20
19
  src/nemo_evaluator_launcher/cli/ls_runs.py
21
20
  src/nemo_evaluator_launcher/cli/ls_tasks.py
@@ -1,117 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- #
16
- import datetime as _dt
17
- import sys
18
- from dataclasses import dataclass
19
- from typing import Optional
20
-
21
- from simple_parsing import field
22
-
23
- from nemo_evaluator_launcher.api.functional import (
24
- get_invocation_benchmarks,
25
- list_all_invocations_summary,
26
- )
27
-
28
-
29
- @dataclass
30
- class Cmd:
31
- """Show a concise invocations table from the exec DB."""
32
-
33
- limit: Optional[int] = field(default=None, alias=["--limit"], help="Max rows")
34
- executor: Optional[str] = field(
35
- default=None, alias=["--executor"], help="Filter by executor"
36
- )
37
- since: Optional[str] = field(
38
- default=None,
39
- alias=["--since"],
40
- help="Filter by ISO date/time (e.g., 2025-08-20 or 2025-08-20T12:00:00)",
41
- )
42
-
43
- def execute(self) -> None:
44
- rows = list_all_invocations_summary()
45
-
46
- # Apply filters
47
- if self.executor:
48
- rows = [
49
- r
50
- for r in rows
51
- if (r.get("executor") or "").lower() == self.executor.lower()
52
- ]
53
-
54
- if self.since:
55
- try:
56
- # Parse with optional time
57
- if "T" in self.since:
58
- since_ts = _dt.datetime.fromisoformat(self.since).timestamp()
59
- else:
60
- since_ts = _dt.datetime.fromisoformat(
61
- self.since + "T00:00:00"
62
- ).timestamp()
63
- rows = [r for r in rows if (r.get("earliest_job_ts") or 0) >= since_ts]
64
- except Exception:
65
- print(
66
- f"Invalid --since value: {self.since}. Use YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS",
67
- file=sys.stderr,
68
- )
69
- sys.exit(2)
70
-
71
- if self.limit is not None and self.limit >= 0:
72
- rows = rows[: self.limit]
73
-
74
- # Print table (always include benchmarks column)
75
- header = [
76
- "invocation_id",
77
- "earliest_job_ts",
78
- "num_jobs",
79
- "executor",
80
- "benchmarks",
81
- ]
82
- # Format ts as ISO without microseconds
83
- table_rows = []
84
- for r in rows:
85
- ts = r.get("earliest_job_ts", 0) or 0
86
- try:
87
- ts_iso = (
88
- _dt.datetime.fromtimestamp(ts).replace(microsecond=0).isoformat()
89
- )
90
- except Exception:
91
- ts_iso = ""
92
- inv = r.get("invocation_id", "")
93
- try:
94
- bmarks = get_invocation_benchmarks(inv)
95
- bmarks_cell = ",".join(bmarks) if bmarks else "unknown"
96
- except Exception:
97
- bmarks_cell = "unknown"
98
- table_rows.append(
99
- [
100
- str(inv),
101
- ts_iso,
102
- str(r.get("num_jobs", 0)),
103
- str(r.get("executor", "")),
104
- bmarks_cell,
105
- ]
106
- )
107
-
108
- widths = [len(h) for h in header]
109
- for tr in table_rows:
110
- for i, cell in enumerate(tr):
111
- if len(cell) > widths[i]:
112
- widths[i] = len(cell)
113
- fmt = " ".join([f"{{:<{w}}}" for w in widths])
114
- print(fmt.format(*header))
115
- print(" ".join(["-" * w for w in widths]))
116
- for tr in table_rows:
117
- print(fmt.format(*tr))
@@ -1,34 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- #
16
- import json
17
- from dataclasses import dataclass
18
-
19
- from nemo_evaluator_launcher.api.functional import get_tasks_list
20
-
21
-
22
- @dataclass
23
- class Cmd:
24
- """List command configuration."""
25
-
26
- def execute(self) -> None:
27
- # TODO(dfridman): modify `get_tasks_list` to return a list of dicts in the first place
28
- data = get_tasks_list()
29
- headers = ["task", "endpoint_type", "harness", "container"]
30
- supported_benchmarks = []
31
- for task_data in data:
32
- assert len(task_data) == len(headers)
33
- supported_benchmarks.append(dict(zip(headers, task_data)))
34
- print(json.dumps(supported_benchmarks, indent=2))