Packagenodus-sdk LanguagePython ≥ 3.10 Version0.1.0 StatusLab / Preview

Workloads API

Submit work by outcome. Nodus matches a nodus:… catalog route, runs toward completion, and recovers when capacity is reclaimed. You never pick a wholesale supplier.

# Playground

Describe the work and its constraints, not a machine SKU. Watch Nodus match a catalog route, run with checkpoints, and recover when capacity is reclaimed. Same lifetime as make demo: match → cost → completion. Customer surface shows nodus:… only; no wholesale brands. No API key required.

Hardware fit and placement are Nodus decisions. You never pick a supplier.

Request

                
Customer view idle
workload
-
catalog sku
-
fit
-
est. cost
-
status
-
generation
-
spend_usd
-
Event log

    # Install

    From the monorepo (published PyPI later). Runtime dependency: httpx.

    install ~
    $ pip install -e sdk/python
    # or: pip install nodus-sdk  (when published)

    # Authentication

    Every request uses Authorization: Bearer <api_key>. Create a key in the console with invite NODUS-LAUNCH.

    VariableDefaultNotes
    NODUS_API_KEY - Required for the SDK.
    NODUS_BASE_URL https://nodus-api-74it.onrender.com Hosted control plane (Render). Cold-starts after idle on the free plan.

    # Quick start

    Describe the work and constraints. Hardware fit, placement, and recovery stay with Nodus.

    quickstart · python ~/your-app
    # export NODUS_API_KEY=<from console signup>
    # export NODUS_BASE_URL=https://nodus-api-74it.onrender.com
    >>> import nodus
    >>>
    >>> with nodus.Client() as client:
    ...     wl = client.run(
    ...         command=["train"],
    ...         requirements={
    ...             "model": "7B fine-tune",
    ...             "expected_runtime_hours": 1,
    ...             "peak_memory_gb": 24,
    ...         },
    ...         budget=100,
    ...         continuity={"mode": "checkpointed", "resume_on_interruption": True},
    ...     )
    ...     done = client.wait(wl.id)
    ...     print(done.status, done.route.offer_id, done.spend_usd)

    # HTTP surface

    Canonical contract: design/api.md and design/openapi.yaml. Mutations require Idempotency-Key.

    EndpointContract
    POST /v1/workloadsSubmit workload revision → 202 + workload_id
    GET /v1/workloadsList workloads for the authenticated tenant
    GET /v1/workloads/{id}Status, customer route (nodus:…), spend
    GET /v1/workloads/{id}/eventsOrdered lifecycle events
    GET /v1/workloads/{id}/ledgerCustomer-safe ledger evidence + settlement
    POST /v1/workloads/{id}/cancelSafe stop
    GET /v1/workloads/{id}/artifactsVerified checkpoint / output manifests
    PUT /v1/webhooksRegister signed customer webhook endpoint

    # Python client

    MethodPurpose
    Client.run(...)Submit from requirements / budget / continuity
    Client.get(id)Fetch current workload
    Client.wait(id)Poll until terminal
    Client.events(id)Lifecycle event page
    Client.cancel(id)Request cancel
    Client.artifacts(id)List verified artifacts

    Workload.route.offer_id is always a Nodus catalog SKU (for example nodus:A100-40-us-local). It is never runpod:, vast:, or a Fleet pool id.

    # Workload states

    accepted → planning → reserving → provisioning → running → recovering? → completed
                                                                      ↘ cancelled | failed

    completed means durable success for the continuity mode (verified checkpoint / artifact path for checkpointed work).

    # Errors

    HTTP errors return JSON {"error": "…", "message": "…"}. The SDK raises nodus.NodusError with status_code and body.

    # Local control plane

    lab ~/nodus
    $ make demo          # embedded lifetime walkthrough
    $ make compose-up    # Postgres + Temporal + MinIO
    $ make build && ./bin/api
    $ make smoke-fleet   # reclaim against a running API

    # Issue API keys

    keys ~/nodus
    $ export NODUS_DATABASE_URL='postgres://nodus:nodus@localhost:5432/nodus?sslmode=disable'
    $ ./bin/nodus-key provision -tenant ten_acme -name "Acme AI" -key-name acme-pilot
    # prints api_key=nk_live_… once; store it; never use ten_dev for partners
    # full checklist: docs/runbooks/pilot.md