Skip to content

refactor(models): migrate models consumers to typed ModelsClient - #1491

Open
maxdubrinsky wants to merge 5 commits into
mainfrom
aircore-827-migrate-models/mdubrinsky
Open

refactor(models): migrate models consumers to typed ModelsClient#1491
maxdubrinsky wants to merge 5 commits into
mainfrom
aircore-827-migrate-models/mdubrinsky

Conversation

@maxdubrinsky

Copy link
Copy Markdown
Contributor

Summary

Migrate models API call sites from sdk.models.* (Stainless SDK) to client_from_platform(sdk, ModelsClient).* (typed HTTP client), following the pattern established in #1277.

Related Issue

AIRCORE-827

Changes

22 files changed across e2e tests, services, plugins, and test utilities:

  • sdk.models.retrieve -> get_model().data()
  • sdk.models.create -> create_model(body=CreateModelEntityRequest(...)).data()
  • sdk.models.update -> update_model(body=UpdateModelEntityRequest(...)).data()
  • sdk.models.list -> list_models(...).items()
  • sdk.models.wait_for_openai_model -> wait_for_openai_model(...)
  • sdk.models.get_provider_route_openai_url -> get_provider_route_openai_url(...)
  • Error imports: APIStatusError->NemoHTTPError, APIConnectionError/APITimeoutError->NemoTransportError
  • Type imports: nemo_platform.types.* -> nemo_platform_plugin.models.types

Skipped (SDK infrastructure, not consumers):

  • packages/models/src/models/resources.py (extended ModelsResource, deleted with SDK)
  • packages/models/tests/test_client.py (tests SDK infrastructure)
  • Auto-generated CLI files (4 files)

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with documentation updates
  • Documentation only
  • Contributor tooling or automation
  • CI, build, or test infrastructure

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification: same API calls, different client
  • Tests not applicable — justification:
  • Documentation updated for user-visible behavior
  • Documentation not applicable — justification: internal refactoring

Verification

  • Pull request title follows the repository's Conventional Commit format
  • Every commit includes an appropriate Signed-off-by: trailer
  • uv run pre-commit run -a passes, or any blocked checks are identified below
  • Targeted tests pass, or tests are marked not applicable above
  • No secrets, API keys, or credentials are included

Targeted validation:

  • py_compile on all 22 files: compile OK
  • uv run ruff check: all checks pass
  • uv run ruff format: all files formatted
  • DCO audit: 1 commit, sign-off matches author email

…ent compat layer

Add 8 new typed HTTP clients in nemo_platform_plugin, following the
proven files/models pattern (types.py + endpoints.py + client.py):

- workspaces: WorkspacesClient (workspace + members CRUD)
- guardrail: GuardrailClient (config CRUD + check)
- projects: ProjectsClient (CRUD)
- agents: AgentsClient (agent + deployment CRUD + invoke)
- auditor: AuditorClient (config/target CRUD + submit + job list/get)
- iron_swarm: IronSwarmClient (manifest CRUD + refresh + run CRUD + validate_model)
- evaluator: EvaluatorClient (submit jobs + results + metrics CRUD)
- data_designer: DataDesignerClient (preview stream + job CRUD)

Add convenience properties to BaseNemoClient so sdk.files, sdk.models,
sdk.workspaces, etc. each return the corresponding typed client via
from_client(self). Add _InferenceNamespace compat shim dispatching
sdk.inference.providers/deployments/virtual_models to the existing
ModelsClient/VirtualModelsClient.

Add NemoResponse.__getattr__ proxy delegating unknown attribute access
to the parsed body, so callers use result.name instead of
result.data().name (eliminates .data() unwrapping at ~980 call sites
during consumer migration).

Purely additive: no existing code changed, only additions. The
Stainless SDK remains in place; this builds the landing pad for the
per-area consumer migration PRs.

AIRCORE-1058

Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
…lient

Add _client property (returns the underlying httpx transport) and
default_headers property (returns the default headers dict) to
BaseNemoClient. Plugin SDK resources (auditor, evaluator, anonymizer,
data-designer, customizer, safe-synthesizer, insights) access
platform._client and platform.default_headers to make raw HTTP calls.
These properties let them work with NemoClient after the spine flip.

AIRCORE-1058

Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
Add __getattr__ to BaseNemoClient that mirrors NeMoPlatform's
plugin SDK discovery: discovers plugin SDK resources via entry
points (discover_sdk) and instantiates them with self as the
platform. Handles sdk.auditor, sdk.evaluator, sdk.agents,
sdk.iron_swarm, sdk.anonymizer, sdk.customizer, and any other
plugin-level resource not covered by convenience properties.

Combined with the _client property (previous commit), this lets
plugin SDK resources work with NemoClient after the spine flip
without any changes to the plugin code.

AIRCORE-1058

Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
@maxdubrinsky
maxdubrinsky marked this pull request as ready for review August 24, 2026 18:26
@maxdubrinsky
maxdubrinsky requested review from a team as code owners August 24, 2026 18:26
@maxdubrinsky
maxdubrinsky force-pushed the aircore-827-migrate-models/mdubrinsky branch from 854a062 to fa107bb Compare August 24, 2026 18:35
@maxdubrinsky
maxdubrinsky marked this pull request as draft August 24, 2026 18:38
@maxdubrinsky
maxdubrinsky force-pushed the aircore-827-migrate-models/mdubrinsky branch 4 times, most recently from 048e329 to 359387f Compare August 24, 2026 21:03
@maxdubrinsky
maxdubrinsky marked this pull request as ready for review August 24, 2026 21:09
Migrate models API call sites from sdk.models.* (Stainless SDK)
to client_from_platform(sdk, ModelsClient).* (typed HTTP client),
following the pattern established in #1277.

22 files changed across e2e tests, services, plugins, and test utilities.
Key migrations:
- sdk.models.retrieve -> get_model().data()
- sdk.models.create -> create_model(body=CreateModelEntityRequest(...)).data()
- sdk.models.update -> update_model(body=UpdateModelEntityRequest(...)).data()
- sdk.models.list -> list_models(...).items()
- sdk.models.wait_for_openai_model -> wait_for_openai_model(...)
- sdk.models.get_provider_route_openai_url -> get_provider_route_openai_url(...)
- Error imports: APIStatusError->NemoHTTPError, APIConnectionError/APITimeoutError->NemoTransportError
- Type imports: nemo_platform.types.* -> nemo_platform_plugin.models.types.*

Skipped (SDK infrastructure, not consumers):
- packages/models/src/models/resources.py (extended ModelsResource, deleted with SDK)
- packages/models/tests/test_client.py (tests SDK infrastructure)
- Auto-generated CLI files (4 files)

AIRCORE-827

Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
@maxdubrinsky
maxdubrinsky force-pushed the aircore-827-migrate-models/mdubrinsky branch from 359387f to 2eec4cf Compare August 24, 2026 22:04
"""Create model entity if missing; ignore already-exists conflicts."""
try:
sdk.models.create(
client_from_platform(sdk, ModelsClient).create_model(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been reading this so my eyes are glazing over, but is "client_from_platform" the best name, or is it something like client_from_sdk or to_client? idk

@maxdubrinsky
maxdubrinsky force-pushed the mdubrinsky/aircore-1058-add-typed-clients-for-remaining-service-areas-nemoclient branch from 2070a49 to c8aeb8a Compare August 25, 2026 16:35
Base automatically changed from mdubrinsky/aircore-1058-add-typed-clients-for-remaining-service-areas-nemoclient to main August 25, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants