Python SDK
The SDK exposes two clients with identical method names — Meshive (synchronous) and AsyncMeshive (asyncio). Both read the same credentials and configuration as the CLI (see Authentication).
Quick start
Section titled “Quick start”from meshive import Meshive
with Meshive() as client: # reads MESHIVE_API_KEY me = client.me() print(me.email, me.user_role)
for ws in client.list_workspaces(): print(ws.namespace_name, ws.status)
pods = client.list_pods("my-workspace") pod = client.get_pod(pods[0].pod_name, "my-workspace") print(pod.status, pod.raw) # .raw holds the full payload
# host view: the machines you contribute to the network machines = client.list_machines() for m in machines: print(m.machine_id, m.status, m.gpu_count, m.gpu_model) machine = client.get_machine(machines[0].machine_id) print(machine.earning_hourly, machine.raw)import asynciofrom meshive import AsyncMeshive
async def main(): async with AsyncMeshive() as client: me = await client.me() print(me.email, me.user_role)
pods = await client.list_pods("my-workspace") pod = await client.get_pod(pods[0].pod_name, "my-workspace") print(pod.status, pod.raw)
machines = await client.list_machines() machine = await client.get_machine(machines[0].machine_id) print(machine.earning_hourly)
asyncio.run(main())Using the client as a context manager (with / async with) ensures the underlying HTTP connection is closed. Otherwise, call client.close() (or await client.close()) yourself.
Constructing a client
Section titled “Constructing a client”Meshive(api_key=None, *, timeout=30.0)AsyncMeshive(api_key=None, *, timeout=30.0)With no arguments, credentials resolve in the usual order (explicit argument › environment variable › meshive login file). You can also pass the key explicitly:
client = Meshive(api_key="meshive_xxxxxxxx")timeout is the per-request timeout in seconds (default 30.0). If no API key can be resolved, the first request raises ConfigurationError.
Methods
Section titled “Methods”Both clients expose the same methods (await them on AsyncMeshive):
| Method | Returns | Description |
|---|---|---|
me() | WhoAmI | The current API key’s owner. |
list_workspaces() | list[Workspace] | Workspaces you can access. |
list_pods(workspace) | list[Pod] | Pods in a workspace (by ID). |
get_pod(pod_name, workspace) | Pod | A single pod. |
list_machines() | list[Machine] | Machines you host. |
get_machine(machine_id) | Machine | A single machine. |
Models
Section titled “Models”Responses are parsed into lightweight dataclasses. Frequently used scalar fields are typed; deeply nested structures aren’t enumerated — the full original payload is preserved on .raw, so the SDK keeps working even when the backend adds fields.
WhoAmI
Section titled “WhoAmI”| Field | Type | Notes |
|---|---|---|
email | str | |
username | str | None | |
user_role | str | |
raw | dict | Full payload. |
Workspace
Section titled “Workspace”| Field | Type | Notes |
|---|---|---|
namespace_name | str | ID — pass to list_pods / get_pod. |
workspace_name | str | Display label. |
description | str | |
member_count | int | |
status | str | |
price_per_hour | str | |
resources | WorkspaceResources | .pod, .storage, .serverless counts. |
created_at / updated_at | datetime | None | |
raw | dict | Full payload. |
| Field | Type | Notes |
|---|---|---|
pod_name | str | ID — pass to get_pod. |
namespace_name | str | Owning workspace ID. |
user_alias | str | Display label. |
status | str | |
rental_type | str | spot / demand. |
price_per_hour | str | |
is_maintenance | bool | |
created_at | datetime | None | |
raw | dict | Full payload — machine, template, request, linked storages, … |
Machine
Section titled “Machine”| Field | Type | Notes |
|---|---|---|
machine_id | str | ID — pass to get_machine. |
name | str | Display label. |
machine_type | str | gpu / cpu / storage. |
status | str | |
gpu_model | str | Empty for cpu/storage machines. |
gpu_count | int | |
earning_hourly | float | |
uptime_rate | float | 0.0–1.0. |
host_tier | str | |
raw | dict | Full payload — specs, full state, pod uses, … |
Errors
Section titled “Errors”All SDK errors subclass MeshiveError:
| Exception | When |
|---|---|
ConfigurationError | No API key could be resolved (raised before any request). |
AuthenticationError | 401 — missing/invalid/expired key, or an inactive account. |
PermissionDeniedError | 403 — the key lacks the required scope. |
NotFoundError | 404 — the resource doesn’t exist. |
RateLimitError | 429 — rate limit exceeded. Exposes .retry_after (seconds, may be None). |
MeshiveAPIError | Any other 4xx/5xx. |
MeshiveAPIError (and its subclasses) carry .status_code, .title, .message, and .raw (the parsed response body).
from meshive import Meshive, MeshiveError, RateLimitError, NotFoundError
try: with Meshive() as client: pod = client.get_pod("does-not-exist", "my-workspace")except NotFoundError as err: print("no such pod:", err.message)except RateLimitError as err: print("slow down; retry after", err.retry_after, "s")except MeshiveError as err: print("request failed:", err)Importable names
Section titled “Importable names”from meshive import ( Meshive, AsyncMeshive, # clients WhoAmI, Workspace, WorkspaceResources, Pod, Machine, # models MeshiveError, ConfigurationError, MeshiveAPIError, # errors AuthenticationError, PermissionDeniedError, NotFoundError, RateLimitError, __version__,)