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.1.2.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.1.2-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: grainvm-0.1.2.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.1.2.tar.gz
Algorithm Hash digest
SHA256 9b5774c0d88af468c409599d8fd17d14e7b0938e20115b765250df20b1ecb382
MD5 3ed37b53a6baab51dc81c46a1e0c3603
BLAKE2b-256 e293533bc8f5b5637b05815063963907df8c53e429438fd10a452c1fc1dee339

See more details on using hashes here.

Provenance

The following attestation bundles were made for grainvm-0.1.2.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.1.2-py3-none-any.whl.

File metadata

  • Download URL: grainvm-0.1.2-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.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 759a4da3ece0488f5cb96c1de99cc20ad38754932aa7083cb94bfd65a55cc359
MD5 8a1bd858bfff73305f4f3ec70e94186e
BLAKE2b-256 23bc53cf1ffdf7d414ad2f0ff4212975c26eb1e193cd32d2cf3517bb2d3fd877

See more details on using hashes here.

Provenance

The following attestation bundles were made for grainvm-0.1.2-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