Skip to main content

Python client for the grain microVM daemon HTTP API

Project description

grainvm — Python client

Lightweight Python SDK for the grain daemon HTTP API. Stdlib only (http.client) — no runtime dependencies. Types and methods mirror the Go client and TypeScript SDK.

Install name: grainvm. Import: import grain.

Install

pip install grainvm

Package: pypi.org/project/grainvm. Requires Python 3.9+.

From a grain checkout (development):

pip install -e /path/to/grain/sdk/python

Quick start (TCP)

Ensure the daemon is up with TCP API enabled (api: 127.0.0.1:7474 is the default config).

from grain import GrainClient, CreateRequest, WAIT_AGENT

grain = GrainClient(
    base_url="http://127.0.0.1:7474",
    token=__import__("os").environ.get("GRAIN_TOKEN", ""),
)

grain.health()

inst = grain.create(
    CreateRequest(persistent=False, cpus=2, memory_mb=2048),
    wait=WAIT_AGENT,
    timeout="3m",
)
print(inst.name, inst.status, inst.ssh_port)

result = grain.exec(inst.name, "uname", ["-a"])
print(result.stdout.strip(), "exit", result.exit_code)

health = grain.agent_health(inst.name)
print(health.agent_version, health.hostname)

stats = grain.stats(inst.name)
print("load1", stats.load1)

grain.delete(inst.name)

Unix socket

from pathlib import Path
from grain import GrainClient

grain = GrainClient.unix(
    str(Path.home() / ".grain" / "grain.sock"),
    token=__import__("os").environ.get("GRAIN_TOKEN", ""),
)
grain.health()
print(grain.list())

Constructor

GrainClient(
    base_url="http://127.0.0.1:7474",  # TCP
    token="",                          # Authorization: Bearer
    socket_path=None,                  # Unix socket path
    timeout=300.0,                     # socket timeout (seconds)
)

GrainClient.unix("~/.grain/grain.sock", token="...")
GrainClient.http("http://127.0.0.1:7474", token="...")

Methods

Method Daemon route
health() GET /healthz
info() GET /info
list() GET /vms
create(req, wait=…, timeout=…) POST /vms
create_stream(req, on_event, …) POST /vms?stream=1 (NDJSON)
get(name) / delete(name) GET / DELETE /vms/{name}
start / stop / shutdown lifecycle
pause / resume / suspend / restore QMP / disk
add_forward / remove_forward live port forwards
exec / exec_stream guest agent exec
agent_health / stats agent probes
readdir / stat / mkdir / remove guest fs
put_file / get_file guest file copy

Errors raise GrainAPIError with status and optional body. Buffered exec returns non-zero guest exit codes in ExecResult.exit_code without raising.

Streamed create

inst = grain.create_stream(
    CreateRequest(persistent=False, cpus=2),
    on_event=lambda ev: print(ev.phase, ev.message or ""),
    wait="ssh",
)

Streamed exec

from grain import ExecOpts

code = grain.exec_stream(
    inst.name,
    ExecOpts(cmd="sh", args=["-c", "echo hi; echo err >&2"]),
    on_frame=lambda f: print(f.type, f.data or f.error or ""),
)

Create wait modes

Pass wait and timeout as keyword args (query parameters), same as the Go client:

Wait Meaning
auto Daemon chooses (agent for golden images, else SSH)
ssh SSH accepts connections
agent Guest agent /health OK
userdata Agent reports userdata finished

Constants: WAIT_AUTO, WAIT_SSH, WAIT_AGENT, WAIT_USERDATA.

Auth

When the daemon has api_token / auth_token set, pass the same value as token or env GRAIN_TOKEN. GET /healthz remains unauthenticated.

Develop / test

cd sdk/python
pip install -e ".[dev]"
pytest -q

Publishing

Maintainers publish to PyPI via GitHub Actions Trusted Publishing (no API token in secrets). See developer/releasing and workflow .github/workflows/publish-python.yml.

API reference

Daemon OpenAPI: api/openapi.yaml. Docs: grainvm.com/reference/python-sdk.

License

Apache-2.0 — same as grain.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

grainvm-0.2.0.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

grainvm-0.2.0-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

Details for the file grainvm-0.2.0.tar.gz.

File metadata

  • Download URL: grainvm-0.2.0.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for grainvm-0.2.0.tar.gz
Algorithm Hash digest
SHA256 126df4bf3586e8b8257beab287a728409aac88758c78d4454a0f691d1e5a4e95
MD5 d31433f71fe96785ae5d35c990ebd649
BLAKE2b-256 eca18b668940744492e9f9f5186747f6be872c2b51bbb7d5639d949b38146ddb

See more details on using hashes here.

Provenance

The following attestation bundles were made for grainvm-0.2.0.tar.gz:

Publisher: publish-python.yml on cxdy/grain

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file grainvm-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: grainvm-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 15.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for grainvm-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b23396d1675d433e2c22bc0aeebc208180f695cc178a952cd2ecc1fe91661f93
MD5 e578dfbadebcb8d8fe0637c2086ebd59
BLAKE2b-256 7f5d76e1bc62bec4e4b72f0536bd5c036124567f860233f56bb9727f1b7f923d

See more details on using hashes here.

Provenance

The following attestation bundles were made for grainvm-0.2.0-py3-none-any.whl:

Publisher: publish-python.yml on cxdy/grain

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page