Python SDK
Reference for fastvm. Auto-generated from the OpenAPI spec + api/helpers.yaml.
Install
pip install fastvmImport
from fastvm import FastvmClient client = FastvmClient() # reads FASTVM_API_KEY / FASTVM_BASE_URL
Top-level helpers
client.*
client.uploadhelper
client.upload( vm_id: str, local_path: str, remote_path: str, *, fetch_timeout_sec: int = 600, exec_timeout_sec: int = 600, ) -> None
Description
Copy a local file or directory into the VM. Uses vms.files.presign
and vms.files.fetch under the hood. Directories are tarred on the
fly before upload and extracted VM-side after fetch.
Streams end-to-end with no intermediate copy to /tmp on the client,
so multi-GB transfers are bounded by VM disk, not RAM. Directory
mode needs the tar binary on the client's PATH (standard on
macOS and Linux; available on modern Windows via bsdtar).
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| vm_id | str | required | Target VM id. |
| local_path | str | required | Local file or directory path. |
| remote_path | str | required | Destination path inside the VM. |
| fetch_timeout_sec | int | 600 | Timeout on the VM-side /files/fetch call. |
| exec_timeout_sec | int | 600 | Timeout on VM-side tar extraction (dir mode only). |
Returns
NoneExample
client.upload(vm.id, "./config.toml", "/etc/app.toml") # file client.upload(vm.id, "./src", "/root/src") # directory (tar-streamed)
client.downloadhelper
client.download( vm_id: str, remote_path: str, local_path: str, *, exec_timeout_sec: int = 600, ) -> None
Description
Copy a file or directory from the VM to the client. Uses
vms.files.presign plus a VM-side exec to classify the path and
stream its contents out. Directories are tarred VM-side and
un-tarred on the client, rooted at ./ so upload and download are
symmetric.
Streams end-to-end with no intermediate copy. Missing paths raise
FileNotFoundError (Python) or FileTransferError with
code: 'ENOENT' (TypeScript).
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| vm_id | str | required | Target VM id. |
| remote_path | str | required | Source path inside the VM. |
| local_path | str | required | Destination path on the client. |
| exec_timeout_sec | int | 600 | Timeout on VM-side exec (classify + stream). |
Returns
NoneExample
client.download(vm.id, "/root/out.log", "./out.log") # file client.download(vm.id, "/var/log", "./log-backup") # directory
client.wait_for_vm_readyhelper
client.wait_for_vm_ready( vm_id: str, *, poll_interval: float = 2.0, timeout: float = 300.0, ) -> VM
Description
Poll GET /v1/vms/{id} until the VM reaches status == "running" or
a terminal failure status. Same polling logic as vms.launch; use
this when you already have a VM id from vms.list() or another flow.
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| vm_id | str | required | Target VM id. |
| poll_interval | float | 2.0 | Seconds between polls. |
| timeout | float | 300.0 | Total wait deadline in seconds. |
Returns
Example
vm = client.vms.retrieve(some_id) vm = client.wait_for_vm_ready(vm.id, timeout=120)
VMs
client.vms.*
client.vms.launchoverride
POST/v1/vmsclient.vms.launch( *, machine_type: MachineType | None = None, snapshot_id: str | None = None, name: str | None = None, metadata: dict[str, str] | None = None, firewall: FirewallPolicy | None = None, wait: bool = True, poll_interval: float = 2.0, wait_timeout: float = 300.0, timeout: float | httpx.Timeout | None = None, max_retries: int = 0, ) -> VM
Description
Launch a VM and (by default) block until it reaches status == "running".
POST /v1/vms returns 201 for immediately-running VMs and 202 for queued
VMs; the override handles both paths transparently by polling
GET /v1/vms/{id}.
Pass wait=false (TS) / wait=False (Python) to skip polling and
return the raw 201/202 body. Pass snapshot_id / snapshotId to
restore from a snapshot instead of cold-booting.
Terminal failure statuses (error, stopped, deleting) raise
VMLaunchError. Polling-deadline exceeded raises VMNotReadyError.
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| machine_type | MachineType | None | None | VM flavor (c1m2, c2m4, ...). Required unless snapshot_id is set. |
| snapshot_id | str | None | None | Restore from snapshot instead of cold-booting. |
| name | str | None | None | Human-readable VM name. |
| metadata | dict[str, str] | None | None | Free-form key/value labels. |
| firewall | FirewallPolicy | None | None | Initial firewall policy. |
| wait | bool | True | Block until RUNNING. Set False for raw 201/202 behavior. |
| poll_interval | float | 2.0 | Seconds between polls when wait=True. |
| wait_timeout | float | 300.0 | Max seconds to wait for RUNNING. Raises VMNotReadyError on exceed. |
| timeout | float | httpx.Timeout | None | None | Per-request HTTP timeout (forwarded to generated launch verbatim). |
| max_retries | int | 0 | Auto-retry on 5xx/connect errors. POST is non-idempotent, default 0. |
Returns
Example
from fastvm import FastvmClient client = FastvmClient() vm = client.vms.launch(machine_type="c1m2", name="dev") print(vm.id, vm.status) # "running" # Restore from snapshot vm = client.vms.launch(snapshot_id="snp_...") # Skip polling — get the raw 201/202 body vm = client.vms.launch(machine_type="c1m2", wait=False)
client.vms.retrieve
GET/v1/vms/{id}client.vms.retrieve( id: str, ) -> VM
Description
Get a VM
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | VM ID (UUID). |
Returns
client.vms.update
PATCH/v1/vms/{id}client.vms.update( id: str, name: str, metadata: Metadata, ) -> VM
Description
Update a VM
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | VM ID (UUID). |
| name | str | — | |
| metadata | Metadata | — |
Returns
client.vms.delete
DELETE/v1/vms/{id}client.vms.delete( id: str, ) -> DeleteResponse
Description
Delete a VM
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | VM ID (UUID). |
Returns
client.vms.set_firewall
PUT/v1/vms/{id}/firewallclient.vms.set_firewall( id: str, mode: FirewallMode, ingress: FirewallRule[], ) -> VM
Description
Replace firewall policy
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | VM ID (UUID). |
| mode | FirewallMode | required | |
| ingress | FirewallRule[] | — |
Returns
client.vms.patch_firewall
PATCH/v1/vms/{id}/firewallclient.vms.patch_firewall( id: str, mode: FirewallMode, ingress: FirewallRule[], ) -> VM
Description
Patch firewall policy
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | VM ID (UUID). |
| mode | FirewallMode | — | |
| ingress | FirewallRule[] | — |
Returns
client.vms.console_token
POST/v1/vms/{id}/console-tokenclient.vms.console_token( id: str, ) -> ConsoleTokenResponse
Description
Mint a console token
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | VM ID (UUID). |
Returns
client.vms.runoverride
POST/v1/vms/{id}/execclient.vms.run( id: str, *, command: str | Sequence[str], timeout_sec: int | None = None, max_retries: int = 0, ) -> ExecVMResponse
Description
Execute a command inside a VM. The override accepts str in addition
to Sequence[str]: plain shell strings are auto-wrapped into
["sh", "-c", "<cmd>"] before hitting the API. Argv-style calls pass
through unchanged.
The wrap guards against Python's silent string-to-chars iteration when
a Sequence[str] parameter is passed a bare string, which would
otherwise produce a nonsensical argv like ["l","s"," ","-","l","a"].
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | Target VM id. |
| command | str | Sequence[str] | required | Shell string (auto-wrapped) or argv. |
| timeout_sec | int | None | None | Server-side execution timeout. |
| max_retries | int | 0 | Auto-retry on 5xx. Non-idempotent, default 0. |
Returns
Example
# Shell strings work — auto-wrapped into ["sh", "-c", ...] result = client.vms.run(vm.id, command="ls -la /root") # Argv lists pass through unchanged result = client.vms.run(vm.id, command=["python3", "main.py", "--flag"]) print(result.exit_code, result.stdout)
VMs.Files
client.vms.files.*
client.vms.files.presign
POST/v1/vms/{id}/files/presignclient.vms.files.presign( id: str, path: str, ) -> FilePresignResponse
Description
Mint signed URLs for uploading a file to a VM
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | VM ID (UUID). |
| path | str | required | Absolute destination path inside the guest filesystem (where the file will land after fetchFileToVm). Used only to scope the staging object key; any value server-side is accepted here. |
Returns
Example
# High-level helpers — handle presign + PUT/GET + fetch + (for dirs) tar # for both file and directory transfers automatically. client.upload(vm.id, "./local/file.txt", "/root/file.txt") client.upload(vm.id, "./local-dir", "/root/remote-dir") client.download(vm.id, "/root/out.log", "./out.log") client.download(vm.id, "/var/log", "./log-backup") # Raw call if you need manual control over the signed-URL flow: presign = client.vms.files.presign(vm.id, path="/root/file.txt")
client.vms.files.fetch
POST/v1/vms/{id}/files/fetchclient.vms.files.fetch( id: str, url: str, path: str, timeout_sec: int, ) -> ExecVMResponse
Description
Fetch a file into a VM from a presigned URL
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | VM ID (UUID). |
| url | str | required | Must be the downloadUrl previously returned by POST /v1/vms/{id}/files/presign (URLs from other sources are rejected). |
| path | str | required | Absolute destination path inside the guest filesystem. |
| timeout_sec | int | — | Per-fetch timeout in seconds. |
Returns
Example
# You usually don't call this directly — client.upload() composes # presign + PUT + fetch in a single call. Use it when you need to # pipe an already-hosted URL (still from /files/presign) into the VM. client.vms.files.fetch(vm.id, url=presign.download_url, path="/root/file.txt")
Snapshots
client.snapshots.*
client.snapshots.list
GET/v1/snapshotsclient.snapshots.list() -> Snapshot[]
Description
List snapshots
Returns
[]client.snapshots.create
POST/v1/snapshotsclient.snapshots.create( vm_id: str, name: str, ) -> Snapshot
Description
Create a snapshot
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| vm_id | str | required | |
| name | str | — | Snapshot name (trimmed + whitespace-collapsed, max 64 runes; longer values are truncated server-side). Auto-generated as snapshot-<8-char-vmId-prefix> if empty. |
Returns
client.snapshots.update
PATCH/v1/snapshots/{id}client.snapshots.update( id: str, name: str, ) -> Snapshot
Description
Rename a snapshot
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | Snapshot ID (UUID). |
| name | str | — |
Returns
client.snapshots.delete
DELETE/v1/snapshots/{id}client.snapshots.delete( id: str, ) -> DeleteResponse
Description
Delete a snapshot
Parameters
| Param | Type | Default | Description |
|---|---|---|---|
| id | str | required | Snapshot ID (UUID). |
Returns
Quotas
client.quotas.*
client.quotas.retrieve
GET/v1/org/quotasclient.quotas.retrieve() -> OrgQuotaUsage
Description
Get org quotas and usage
Returns
Types
Shared schemas referenced in parameters and return values.
DeleteResponse
object| Field | Type | Description |
|---|---|---|
| id | str | |
| deleted | bool |
VMStatus
primitiveprovisioning, running, stopped, deleting, error. Terminal failure statuses are error and stopped; any other non-running value indicates the VM is still transitioning. Additional values may be introduced in future server versions; clients should treat unknown values as "in transition" rather than as hard errors.SnapshotStatus
primitivecreating, ready, error. Additional values may be introduced in future server versions.MachineType
primitivec1m2, c2m4). Controls CPU and memory allocation. Must be supplied on launch unless restoring from a snapshot.VM
object| Field | Type | Description |
|---|---|---|
| id | str | |
| name | str | |
| org_id | str | |
| machine_name | str | |
| source_name | str | Source snapshot or image name (empty on fresh boot). |
| firewall | FirewallPolicy | |
| metadata | Metadata | |
| public_ipv6 | str | |
| cpu | int | |
| memory_mi_b | int | |
| disk_gi_b | int | |
| status | VMStatus | |
| created_at | str | |
| deleted_at | unknown |
Snapshot
object| Field | Type | Description |
|---|---|---|
| id | str | |
| name | str | |
| org_id | str | |
| vm_id | str | |
| firewall | FirewallPolicy | |
| metadata | Metadata | |
| status | SnapshotStatus | |
| created_at | str |
FirewallMode
primitiveopen (allow all inbound traffic), restricted (deny by default; only rules listed in ingress are allowed). Additional values may be introduced in future server versions.FirewallRule
object| Field | Type | Description |
|---|---|---|
| protocol | str | IP protocol. Known values: tcp, udp. Additional values may be introduced in future server versions. |
| port_start | int | Start of port range (inclusive). Required. |
| port_end | int | End of port range (inclusive). Omit for single-port rules. |
| source_cidrs | list[str] | Allowed source CIDRs in IPv6 notation (e.g. 2001:db8::/32). Omit or empty to allow any source. IPv4 CIDRs are rejected. |
| description | str |
FirewallPolicy
object| Field | Type | Description |
|---|---|---|
| mode | FirewallMode | |
| ingress | FirewallRule[] |
Metadata
objectExecVMResponse
objectPOST /v1/vms/{id}/exec under Accept: application/json. The server collects the streamed events and returns this aggregate once the command exits. Per-stream output is capped at 4 MiB; overflow bytes are dropped and signalled via stdoutTruncated / stderrTruncated. Streaming clients (Accept: application/x-ndjson) receive every byte without a cap.| Field | Type | Description |
|---|---|---|
| exit_code | int | |
| stdout | str | |
| stderr | str | |
| timed_out | bool | |
| stdout_truncated | bool | True if the collector dropped stdout bytes past the 4 MiB cap. |
| stderr_truncated | bool | True if the collector dropped stderr bytes past the 4 MiB cap. |
| duration_ms | int |
FilePresignResponse
objectuploadUrl, and either side GETs them back via downloadUrl. URLs expire after expiresInSec seconds and the staging object is auto-deleted after about a day.| Field | Type | Description |
|---|---|---|
| upload_url | str | Presigned PUT URL for the staging object. Accepts Content-Type: application/octet-stream. Used by the client on upload, or by the VM (via an exec'd curl -T -) on download. |
| download_url | str | Presigned GET URL for the same staging object. Used by the VM (via POST /v1/vms/{id}/files/fetch) on upload, or by the client (via httpx.stream / curl) on download. |
| expires_in_sec | int | Lifetime of both URLs in seconds. |
| max_upload_bytes | int | Upper bound on upload size (equals the VM's disk size in bytes). |
ConsoleTokenResponse
object| Field | Type | Description |
|---|---|---|
| token | str | |
| expires_in_sec | int | |
| websocket_path | str | Relative WebSocket path; combine with your API host as wss://<host><websocketPath>?session=<token>. |
OrgQuotaValues
object| Field | Type | Description |
|---|---|---|
| vcpu | int | |
| memory_mi_b | int | |
| disk_gi_b | int | |
| snapshot_count | int |
OrgQuotaUsage
object| Field | Type | Description |
|---|---|---|
| org_id | str | |
| limits | OrgQuotaValues | |
| usage | OrgQuotaValues |
HealthResponse
object| Field | Type | Description |
|---|---|---|
| status | str |