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.
Metadata
Release files for grainvm 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| grainvm-0.2.0.tar.gz | 19.0 kB | With provenance | Details for grainvm-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| grainvm-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for grainvm-0.2.0-py3-none-any.whl |
Total release size: 34.4 kB
Release files / grainvm-0.2.0.tar.gz
| Download URL | grainvm-0.2.0.tar.gz |
|---|---|
| Size | 19.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
126df4bf3586e8b8257beab287a728409aac88758c78d4454a0f691d1e5a4e95
|
|
BLAKE2b-256 checksum How to use checksums |
eca18b668940744492e9f9f5186747f6be872c2b51bbb7d5639d949b38146ddb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.
Transparency logRelease files / grainvm-0.2.0-py3-none-any.whl
| Download URL | grainvm-0.2.0-py3-none-any.whl |
|---|---|
| Size | 15.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b23396d1675d433e2c22bc0aeebc208180f695cc178a952cd2ecc1fe91661f93
|
|
BLAKE2b-256 checksum How to use checksums |
7f5d76e1bc62bec4e4b72f0536bd5c036124567f860233f56bb9727f1b7f923d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.
Transparency logSecurity for grainvm 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for grainvm-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.