refactor(cli): return resource lists from the control plane client

This commit is contained in:
Hugo Durand
2026-09-22 14:35:31 -04:00
parent 1afaca35a0
commit 04a78aafad
5 changed files with 95 additions and 81 deletions
+10 -36
View File
@@ -375,14 +375,8 @@ def _source_of(resource: object) -> str | None:
def find_deployment_by_name(
client: HostBackendClient, name: str
) -> ExistingDeployment | None:
listed = client.list_deployments(name_contains=name)
resources = listed.get("resources", []) if isinstance(listed, dict) else []
for resource in resources:
if (
isinstance(resource, dict)
and resource.get("name") == name
and resource.get("id")
):
for resource in client.list_deployments(name_contains=name):
if resource.get("name") == name and resource.get("id"):
return ExistingDeployment(str(resource["id"]), _source_of(resource))
return None
@@ -750,14 +744,11 @@ def _poll_revision_status(
) -> tuple[str, str | None]:
"""Poll latest revision status until terminal status or timeout."""
em = _get_emitter()
revisions_resp = client.list_revisions(deployment_id, limit=1)
resources = (
revisions_resp.get("resources", []) if isinstance(revisions_resp, dict) else []
)
if not resources:
revisions = client.list_revisions(deployment_id, limit=1)
if not revisions:
return "", None
revision_id = str(resources[0]["id"])
revision_id = str(revisions[0]["id"])
last_status = ""
deadline = time.time() + timeout_seconds
start_time = time.monotonic()
@@ -2052,16 +2043,10 @@ def _deploy_cmd(
@deploy.command("list", help="[Beta] List LangSmith Deployments.")
def deploy_list(api_key: str | None, host_url: str | None, name_contains: str) -> None:
client = _create_host_backend_client(host_url, api_key)
response = _call_host_backend_with_optional_tenant(
deployments = _call_host_backend_with_optional_tenant(
client,
lambda c: c.list_deployments(name_contains=name_contains),
)
resources = response.get("resources") if isinstance(response, dict) else None
deployments = (
[item for item in resources if isinstance(item, dict)]
if isinstance(resources, list)
else []
)
if not deployments:
click.echo("No deployments found.")
return
@@ -2101,16 +2086,10 @@ def deploy_revisions_list(
api_key: str | None, host_url: str | None, limit: int, deployment_id: str
) -> None:
client = _create_host_backend_client(host_url, api_key)
response = _call_host_backend_with_optional_tenant(
revisions = _call_host_backend_with_optional_tenant(
client,
lambda c: c.list_revisions(deployment_id, limit=limit),
)
resources = response.get("resources") if isinstance(response, dict) else None
revisions = (
[item for item in resources if isinstance(item, dict)]
if isinstance(resources, list)
else []
)
if not revisions:
click.echo(f"No revisions found for deployment {deployment_id}.")
return
@@ -2260,17 +2239,12 @@ def deploy_logs(
dep_id = found.id
if log_type == "build" and not revision_id:
revisions_resp = client.list_revisions(dep_id, limit=1)
resources = (
revisions_resp.get("resources", [])
if isinstance(revisions_resp, dict)
else []
)
if not resources:
revisions = client.list_revisions(dep_id, limit=1)
if not revisions:
raise click.ClickException(
"No revisions found for this deployment. Cannot fetch build logs."
)
revision_id = str(resources[0]["id"])
revision_id = str(revisions[0]["id"])
click.secho(f"Using latest revision: {revision_id}", fg="cyan")
payload: dict = {"limit": limit, "order": "desc"}
+24 -9
View File
@@ -83,6 +83,15 @@ def _without_api_path(path: str) -> str:
return path
def _resources(payload: object) -> list[dict[str, Any]]:
if not isinstance(payload, dict):
return []
resources = payload.get("resources")
if not isinstance(resources, list):
return []
return [item for item in resources if isinstance(item, dict)]
class HostBackendError(click.ClickException):
"""Raised when the host backend returns an error response."""
@@ -172,11 +181,13 @@ class HostBackendClient:
payload["secrets"] = secrets
return self._request("POST", "/v2/deployments", payload)
def list_deployments(self, name_contains: str = "") -> dict[str, Any]:
return self._request(
"GET",
"/v2/deployments",
params={"name_contains": name_contains},
def list_deployments(self, name_contains: str = "") -> list[dict[str, Any]]:
return _resources(
self._request(
"GET",
"/v2/deployments",
params={"name_contains": name_contains},
)
)
def get_deployment(self, deployment_id: str) -> dict[str, Any]:
@@ -251,10 +262,14 @@ class HostBackendClient:
payload["secrets"] = secrets
return self._request("PATCH", f"/v2/deployments/{deployment_id}", payload)
def list_revisions(self, deployment_id: str, limit: int = 1) -> dict[str, Any]:
return self._request(
"GET",
f"/v2/deployments/{deployment_id}/revisions?limit={limit}",
def list_revisions(
self, deployment_id: str, limit: int = 1
) -> list[dict[str, Any]]:
return _resources(
self._request(
"GET",
f"/v2/deployments/{deployment_id}/revisions?limit={limit}",
)
)
def get_revision(self, deployment_id: str, revision_id: str) -> dict[str, Any]: