# The resource API

> Read, watch, apply and patch any Nodus kind from Python with nodus.api, the generic client under the SDK.

Source: https://nodus-platform-site.pages.dev/docs/guides/python/api/
Build revision: 211ad9f836655b1c3a2668c4693e442471f28614

`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.

```python
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.

## Health

```python
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.

## Clients and retries

```python
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.
