Skip to content

The resource API

View Markdown

nodus.api is the generic client the rest of the SDK is built on. It works with every kind, including ones the Modal-shaped layer does not wrap, and takes the same objects as nodus apply and kubectl.

import nodus
job = nodus.api.get("Job", "finetune-llama")
for obj in nodus.api.list("Job", label_selector={"team": "nlp"}):
print(obj["metadata"]["name"], obj["status"]["phase"])
for event in nodus.api.watch("Job", field_selector={"metadata.name": "finetune-llama"}):
print(event["type"], event["object"]["status"].get("phase"))
nodus.api.apply("job.yaml") # three-way merge, like nodus apply
nodus.api.patch("Job", "finetune-llama", {"spec": {"maxCostUSD": "80.00"}})
estimate, etag = nodus.api.estimate(obj) # dry-run
nodus.api.create(obj, if_match=etag) # launch exactly what was estimated
for line in nodus.api.logs("Job", "finetune-llama", follow=True):
print(line, end="")
nodus.api.delete("Job", "finetune-llama")

Objects are plain dicts shaped like the kinds in the API reference.

nodus.api.healthz() # True when the API process answers
ready = nodus.api.readyz()
print(ready.ready, ready.release, ready.degraded, ready.failing)

readyz() returns what /readyz reports instead of raising when the server is not ready: release is the commit it runs, degraded lists checks that fail without making it unready, and failing names the check that did. Neither call retries, so a probe sees one answer.

client = nodus.Client(context="acme", project="nlp") # or api_key=, api_url=, org=
client.get("Sandbox", "agent-1")
nodus.api.set_default_client(client) # what module-level calls and the rest of the SDK use

Reads and watches are retried on connection errors, rate limits and 503 responses, with exponential backoff that honours Retry-After, for up to 5 minutes. Every create sends an Idempotency-Key, so a retried create never makes a duplicate. When the outcome of a write is unknown, the raised error carries idempotency_key: retry the same call with that key to finish it safely.