Skip to content

Commit 211e58d

Browse files
committed
refactor: flip spine to NemoClient + swap all SDK imports
Flip sdk_factory to return NemoClient/AsyncNemoClient instead of NeMoPlatform/AsyncNeMoPlatform. Rewrite the bridge adapter to use from_client() instead of reading Stainless private attrs. Swap all 528 consumer files from 'from nemo_platform' imports to typed client imports (nemo_platform_plugin.client.client, .errors, .types, etc.). Type annotations changed: NeMoPlatform -> NemoClient, AsyncNeMoPlatform -> AsyncNemoClient throughout. Method calls use new typed client method names (get_workspace, create_guardrail_config, etc.) which are available on the typed clients from PR 1. Old method names (retrieve, create, list, etc.) are also available via the compat layer from PR 2. The Stainless SDK remains in place (deletion is PR 10). 24 files that still import from nemo_platform (enhanced NeMoPlatform client, error handlers, code generators) are left as-is since the SDK is still present and importable. Pyproject.toml files are NOT changed (SDK deps kept) — removal happens in PR 10 when the SDK is actually deleted. AIRCORE-827 Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
1 parent d0eddf9 commit 211e58d

528 files changed

Lines changed: 3671 additions & 3757 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

agents/nemo-studio-assistant/src/nemo_studio_assistant/register.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@
1010
from urllib.parse import urlencode
1111

1212
import httpx
13-
from nemo_platform import NeMoPlatform
13+
from nemo_platform_plugin.client.client import NemoClient
1414
from pydantic import BaseModel
1515

1616
DEFAULT_WORKSPACE = "default"
1717
STUDIO_CALLBACK_PATH = "/studio/api/assistant/mcp/{session_id}"
1818
STUDIO_CALLBACK_TIMEOUT_SECONDS = 3600.0
1919
_READ_ONLY_SDK_ACTIONS = frozenset({"get", "get_logs", "get_status", "list", "read", "retrieve", "search"})
2020

21-
_clients: dict[str, NeMoPlatform] = {}
21+
_clients: dict[str, NemoClient] = {}
2222

2323

2424
def _active_workspace() -> str:
2525
return os.environ.get("NMP_WORKSPACE") or DEFAULT_WORKSPACE
2626

2727

28-
def _get_client(workspace: str) -> NeMoPlatform:
28+
def _get_client(workspace: str) -> NemoClient:
2929
request_workspace = workspace.strip()
3030
if not request_workspace:
3131
raise ValueError("workspace is required")
@@ -34,7 +34,7 @@ def _get_client(workspace: str) -> NeMoPlatform:
3434
kwargs: dict[str, Any] = {"workspace": request_workspace}
3535
if base_url:
3636
kwargs["base_url"] = base_url
37-
_clients[request_workspace] = NeMoPlatform(**kwargs)
37+
_clients[request_workspace] = NemoClient(**kwargs)
3838
return _clients[request_workspace]
3939

4040

@@ -50,7 +50,7 @@ def _serialize(obj: Any) -> Any:
5050
return str(obj)
5151

5252

53-
def _resolve_resource(client: NeMoPlatform, resource_path: str) -> Any:
53+
def _resolve_resource(client: NemoClient, resource_path: str) -> Any:
5454
current = client
5555
for part in resource_path.split("."):
5656
if not part or part.startswith("_"):

docs/evaluator/test_doc_examples.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from nemo_evaluator.sdk import Evaluator
3131
from nemo_evaluator.shared.metric_bundles.bundles import MetricBundlePackagerPolicyError
3232
from nemo_evaluator_sdk.metrics.protocol import MetricInput, MetricOutput, MetricOutputSpec, MetricResult
33-
from nemo_platform import NeMoPlatform
33+
from nemo_platform_plugin.client.client import NemoClient
3434

3535

3636
class _CustomMetric:
@@ -88,7 +88,7 @@ def _evaluator() -> Evaluator:
8888
Client construction and the ``submit`` argument guard are both offline; the
8989
guard runs before any executor/HTTP work.
9090
"""
91-
client = NeMoPlatform(base_url="http://localhost:8080", workspace="default")
91+
client = NemoClient(base_url="http://localhost:8080", workspace="default")
9292
return client.evaluator
9393

9494

e2e/agents_deploy_helpers.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import httpx
2828
import pytest
2929
from nemo_agents_plugin.entities import NAT_WORKFLOW_CONFIG_FORMAT, NEMO_AGENTS_SPEC_CONFIG_FORMAT
30-
from nemo_platform import NeMoPlatform
30+
from nemo_platform_plugin.client.client import NemoClient
3131
from nmp.testing import MockProviderResponse, add_mock_provider
3232

3333
# The mocked completion the deployed agent must round-trip back to the caller.
@@ -116,23 +116,23 @@ def _page_data(page: Any) -> list[dict[str, Any]]:
116116
return data
117117

118118

119-
def delete_agent_if_exists(sdk: NeMoPlatform, *, workspace: str, name: str) -> None:
119+
def delete_agent_if_exists(sdk: NemoClient, *, workspace: str, name: str) -> None:
120120
try:
121-
sdk.agents.delete(name, workspace=workspace)
121+
sdk.agents.delete_agent(name, workspace=workspace)
122122
except httpx.HTTPStatusError as exc:
123123
if exc.response.status_code != 404:
124124
raise
125125

126126

127-
def delete_deployment_if_exists(sdk: NeMoPlatform, *, workspace: str, name: str) -> None:
127+
def delete_deployment_if_exists(sdk: NemoClient, *, workspace: str, name: str) -> None:
128128
try:
129-
sdk.agents.deployments.delete(name, workspace=workspace)
129+
sdk.agents.delete_deployment(name, workspace=workspace)
130130
except httpx.HTTPStatusError as exc:
131131
if exc.response.status_code != 404:
132132
raise
133133

134134

135-
def get_deployment_log_text(sdk: NeMoPlatform, *, workspace: str, name: str) -> str:
135+
def get_deployment_log_text(sdk: NemoClient, *, workspace: str, name: str) -> str:
136136
try:
137137
response = sdk._client.get(
138138
f"/apis/agents/v2/workspaces/{workspace}/deployments/{name}/logs",
@@ -148,7 +148,7 @@ def get_deployment_log_text(sdk: NeMoPlatform, *, workspace: str, name: str) ->
148148

149149

150150
def wait_for_deployment_deleted(
151-
sdk: NeMoPlatform,
151+
sdk: NemoClient,
152152
*,
153153
workspace: str,
154154
name: str,
@@ -158,7 +158,7 @@ def wait_for_deployment_deleted(
158158
last_status: str | None = None
159159
while time.monotonic() < deadline:
160160
try:
161-
deployment = sdk.agents.deployments.get(name, workspace=workspace)
161+
deployment = sdk.agents.get_deployment(name, workspace=workspace)
162162
last_status = deployment.get("status")
163163
except httpx.HTTPStatusError as exc:
164164
if exc.response.status_code == 404:
@@ -169,7 +169,7 @@ def wait_for_deployment_deleted(
169169

170170

171171
def wait_for_deployment_running(
172-
sdk: NeMoPlatform,
172+
sdk: NemoClient,
173173
*,
174174
workspace: str,
175175
name: str,
@@ -178,7 +178,7 @@ def wait_for_deployment_running(
178178
deadline = time.monotonic() + timeout_seconds
179179
last_deployment: dict[str, Any] | None = None
180180
while time.monotonic() < deadline:
181-
deployment = sdk.agents.deployments.get(name, workspace=workspace)
181+
deployment = sdk.agents.get_deployment(name, workspace=workspace)
182182
last_deployment = deployment
183183
status = deployment["status"]
184184
if status == "running":
@@ -191,7 +191,7 @@ def wait_for_deployment_running(
191191

192192

193193
def run_agent_deploy_and_invoke(
194-
sdk: NeMoPlatform,
194+
sdk: NemoClient,
195195
*,
196196
workspace: str,
197197
deployment_mode: str,
@@ -233,7 +233,7 @@ def run_agent_deploy_and_invoke(
233233
served_models={model_name: model_name},
234234
)
235235

236-
sdk.agents.create(
236+
sdk.agents.create_agent(
237237
workspace=workspace,
238238
name=agent_name,
239239
config=_mock_backed_agent_config(
@@ -245,7 +245,7 @@ def run_agent_deploy_and_invoke(
245245
)
246246

247247
try:
248-
created = sdk.agents.deployments.create(
248+
created = sdk.agents.create_deployment(
249249
workspace=workspace,
250250
agent=agent_name,
251251
name=deployment_name,
@@ -276,7 +276,7 @@ def run_agent_deploy_and_invoke(
276276

277277
sdk.models.wait_for_openai_model(model_name, workspace=workspace)
278278

279-
response = sdk.agents.invoke(
279+
response = sdk.agents.invoke_agent(
280280
workspace=workspace,
281281
agent=agent_name,
282282
input="What is 12 multiplied by 8?",
@@ -294,7 +294,7 @@ def run_agent_deploy_and_invoke(
294294

295295

296296
def run_container_agent_deploy_and_invoke(
297-
sdk: NeMoPlatform,
297+
sdk: NemoClient,
298298
*,
299299
workspace: str,
300300
deployment_mode: str,

e2e/auditor/conftest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
"""Fixtures for auditor plugin e2e tests."""
55

66
import pytest
7-
from nemo_platform import NeMoPlatform
7+
from nemo_platform_plugin.client.client import NemoClient
88

99

1010
@pytest.fixture
11-
def auditor_url(sdk: NeMoPlatform) -> str:
11+
def auditor_url(sdk: NemoClient) -> str:
1212
"""Root URL for raw httpx calls to the auditor plugin (filter/sort params not in SDK)."""
1313
return str(sdk.base_url).rstrip("/") + "/apis/auditor"

e2e/auditor/test_audit_job.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from contextlib import suppress
2020

2121
import pytest
22-
from nemo_platform import NeMoPlatform
22+
from nemo_platform_plugin.client.client import NemoClient
2323
from nmp.testing import add_mock_provider, short_unique_name
2424

2525
from e2e.auditor.utils import minimal_audit_config, unique_name
@@ -44,25 +44,25 @@ def _chat_completion(content: str = "I'm happy to help!") -> dict:
4444
}
4545

4646

47-
def _wait_for_audit_job(sdk: NeMoPlatform, job_name: str, workspace: str) -> str:
47+
def _wait_for_audit_job(sdk: NemoClient, job_name: str, workspace: str) -> str:
4848
deadline = time.monotonic() + AUDIT_JOB_TIMEOUT_SECONDS
4949
while time.monotonic() < deadline:
50-
status_resp = sdk.jobs.get_status(name=job_name, workspace=workspace)
50+
status_resp = sdk.jobs.get_job_status(name=job_name, workspace=workspace)
5151
status = str(status_resp.status)
5252
if status in TERMINAL_STATUSES:
5353
return status
5454
time.sleep(AUDIT_JOB_POLL_INTERVAL_SECONDS)
5555
raise TimeoutError(f"Audit job {job_name!r} did not complete within {AUDIT_JOB_TIMEOUT_SECONDS}s")
5656

5757

58-
def _cleanup_audit_job(sdk: NeMoPlatform, job_name: str, workspace: str) -> None:
58+
def _cleanup_audit_job(sdk: NemoClient, job_name: str, workspace: str) -> None:
5959
with suppress(Exception):
60-
sdk.jobs.cancel(name=job_name, workspace=workspace)
60+
sdk.jobs.cancel_job(name=job_name, workspace=workspace)
6161
with suppress(Exception):
62-
sdk.jobs.delete(name=job_name, workspace=workspace)
62+
sdk.jobs.delete_job(name=job_name, workspace=workspace)
6363

6464

65-
def _add_mock_provider_or_skip(sdk: NeMoPlatform, workspace: str, name: str) -> str:
65+
def _add_mock_provider_or_skip(sdk: NemoClient, workspace: str, name: str) -> str:
6666
"""Create a mock inference provider, skipping the test if the deployment doesn't support one."""
6767
try:
6868
provider = add_mock_provider(
@@ -86,27 +86,27 @@ def _add_mock_provider_or_skip(sdk: NeMoPlatform, workspace: str, name: str) ->
8686

8787

8888
@pytest.fixture(scope="module")
89-
def audit_workspace(sdk: NeMoPlatform) -> Iterator[str]:
89+
def audit_workspace(sdk: NemoClient) -> Iterator[str]:
9090
name = short_unique_name("e2e-audit")
91-
sdk.workspaces.create(name=name)
91+
sdk.workspaces.create_workspace(name=name)
9292
try:
9393
yield name
9494
finally:
9595
with suppress(Exception):
96-
sdk.workspaces.delete(name)
96+
sdk.workspaces.delete_workspace(name)
9797

9898

9999
@pytest.fixture(scope="module")
100-
def mock_provider_name(sdk: NeMoPlatform, audit_workspace: str) -> str:
100+
def mock_provider_name(sdk: NemoClient, audit_workspace: str) -> str:
101101
"""Create a canned-response mock provider for the module; workspace deletion cascades cleanup."""
102102
provider_name = short_unique_name("audit-mock")
103103
return _add_mock_provider_or_skip(sdk, audit_workspace, provider_name)
104104

105105

106106
@pytest.fixture(scope="module")
107-
def audit_config_name(sdk: NeMoPlatform, audit_workspace: str) -> Iterator[str]:
107+
def audit_config_name(sdk: NemoClient, audit_workspace: str) -> Iterator[str]:
108108
name = short_unique_name("e2e-audit-cfg")
109-
sdk.auditor.configs.create(
109+
sdk.auditor.create_audit_config(
110110
workspace=audit_workspace,
111111
name=name,
112112
**minimal_audit_config(plugins={"probe_spec": "test.Test", "detector_spec": "auto"}),
@@ -115,13 +115,13 @@ def audit_config_name(sdk: NeMoPlatform, audit_workspace: str) -> Iterator[str]:
115115
yield name
116116
finally:
117117
with suppress(Exception):
118-
sdk.auditor.configs.delete(workspace=audit_workspace, name=name)
118+
sdk.auditor.delete_audit_config(workspace=audit_workspace, name=name)
119119

120120

121121
@pytest.fixture(scope="module")
122-
def audit_target_name(sdk: NeMoPlatform, audit_workspace: str, mock_provider_name: str) -> Iterator[str]:
122+
def audit_target_name(sdk: NemoClient, audit_workspace: str, mock_provider_name: str) -> Iterator[str]:
123123
name = short_unique_name("e2e-audit-tgt")
124-
sdk.auditor.targets.create(
124+
sdk.auditor.create_audit_target(
125125
workspace=audit_workspace,
126126
name=name,
127127
type="openai",
@@ -143,15 +143,15 @@ def audit_target_name(sdk: NeMoPlatform, audit_workspace: str, mock_provider_nam
143143
yield name
144144
finally:
145145
with suppress(Exception):
146-
sdk.auditor.targets.delete(workspace=audit_workspace, name=name)
146+
sdk.auditor.delete_audit_target(workspace=audit_workspace, name=name)
147147

148148

149149
# ---- Tests ----
150150

151151

152152
@pytest.mark.skip("re-enable after auditor image rebuilt")
153153
def test_audit_job_submit_blank_probe(
154-
sdk: NeMoPlatform,
154+
sdk: NemoClient,
155155
audit_workspace: str,
156156
mock_provider_name: str,
157157
) -> None:
@@ -180,7 +180,7 @@ def test_audit_job_submit_blank_probe(
180180
},
181181
}
182182

183-
job = sdk.auditor.submit(config=config, target=target, workspace=audit_workspace)
183+
job = sdk.auditor.submit_audit(config=config, target=target, workspace=audit_workspace)
184184
job_name = job.name
185185
try:
186186
final_status = _wait_for_audit_job(sdk, job_name, audit_workspace)
@@ -194,13 +194,13 @@ def test_audit_job_submit_blank_probe(
194194

195195
@pytest.mark.skip("re-enable after auditor image rebuilt")
196196
def test_audit_job_submit_with_entity_refs(
197-
sdk: NeMoPlatform,
197+
sdk: NemoClient,
198198
audit_workspace: str,
199199
audit_config_name: str,
200200
audit_target_name: str,
201201
) -> None:
202202
"""Submit an audit job using stored entity name references and verify completion."""
203-
job = sdk.auditor.submit(
203+
job = sdk.auditor.submit_audit(
204204
config=f"{audit_workspace}/{audit_config_name}",
205205
target=f"{audit_workspace}/{audit_target_name}",
206206
workspace=audit_workspace,
@@ -216,13 +216,13 @@ def test_audit_job_submit_with_entity_refs(
216216

217217

218218
def test_audit_job_appears_in_list(
219-
sdk: NeMoPlatform,
219+
sdk: NemoClient,
220220
audit_workspace: str,
221221
audit_config_name: str,
222222
audit_target_name: str,
223223
) -> None:
224224
"""Submitted audit job appears in list_jobs() with its name."""
225-
job = sdk.auditor.submit(
225+
job = sdk.auditor.submit_audit(
226226
config=f"{audit_workspace}/{audit_config_name}",
227227
target=f"{audit_workspace}/{audit_target_name}",
228228
workspace=audit_workspace,

e2e/auditor/test_cli.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111

1212
import json
1313

14-
from nemo_platform import NeMoPlatform
14+
from nemo_platform_plugin.client.client import NemoClient
1515
from nmp.testing import assert_exit_0, run_nemo_local
1616

1717
from e2e.auditor.utils import minimal_audit_config, minimal_audit_target, unique_name
1818

1919

20-
def test_cli_config_create_list_delete(sdk: NeMoPlatform, workspace: str) -> None:
20+
def test_cli_config_create_list_delete(sdk: NemoClient, workspace: str) -> None:
2121
name = unique_name("cli-cfg")
2222
base_url = str(sdk.base_url)
2323

@@ -49,7 +49,7 @@ def test_cli_config_create_list_delete(sdk: NeMoPlatform, workspace: str) -> Non
4949
assert all(item["name"] != name for item in listed["data"])
5050

5151

52-
def test_cli_target_create_list_delete(sdk: NeMoPlatform, workspace: str) -> None:
52+
def test_cli_target_create_list_delete(sdk: NemoClient, workspace: str) -> None:
5353
name = unique_name("cli-tgt")
5454
base_url = str(sdk.base_url)
5555

@@ -75,7 +75,7 @@ def test_cli_target_create_list_delete(sdk: NeMoPlatform, workspace: str) -> Non
7575
assert_exit_0(result, "CLI delete target")
7676

7777

78-
def test_cli_config_update(sdk: NeMoPlatform, workspace: str) -> None:
78+
def test_cli_config_update(sdk: NemoClient, workspace: str) -> None:
7979
name = unique_name("cli-upd")
8080
base_url = str(sdk.base_url)
8181

0 commit comments

Comments
 (0)