> ## Documentation Index
> Fetch the complete documentation index at: https://celesto.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Celesto Python class reference

> Celesto class reference: the Python API for creating microVM sandboxes, running commands over the selected control channel, and managing the full sandbox lifecycle.

## Overview

The `Celesto` class provides a user-friendly interface for creating and managing microVMs. It supports automatic configuration, context manager usage, and command execution over the selected control channel.

## Constructor

```python theme={null} theme={null}
Celesto(
    config: VMConfig | None = None,
    *,
    vm_id: str | None = None,
    image: str | None = None,
    data_dir: Path | None = None,
    socket_dir: Path | None = None,
    backend: str | None = None,
    os: GuestOS | str | None = None,
    qemu_machine: Literal["auto", "microvm", "q35"] = "auto",
    memory: int | None = None,
    disk_size: int | None = None,
    ssh_user: str = "root",
    ssh_key_path: str | None = None,
    ssh_password: str | None = None,
    comm_channel: Literal["ssh", "vsock"] | None = None,
    internet_settings: InternetSettings | dict | None = None,
    mounts: list[str] | None = None,
    writable_mounts: bool = False,
    callbacks: list[Callback] | None = None,
    state_manager: StateManagerProtocol | None = None,
)
```

**config** `VMConfig | None` (default: None)

VM configuration. Mutually exclusive with `vm_id`. If omitted (and `vm_id` is omitted), Celesto auto-creates a default configuration that can run commands over vsock or SSH.

**vm\_id** `str | None` (default: None)

ID of an existing VM to reconnect to. Mutually exclusive with `config`.

**image** `str | None` (default: None)

Disk image to boot. Accepts:

* A published S3 image URI (`s3://bucket/images/alpine/`) — the manifest defines the OS, so `os=` must be omitted.
* A local `qcow2` file path (`/var/lib/vms/win11.qcow2`, `~/win11/disk.qcow2`) or `file://` URI — requires `os=` since the file alone doesn't self-identify.

Mutually exclusive with `config` and `vm_id`. Local images are only supported for `os="windows"` in this release; see [Windows guests](/docs/smolvm/guides/windows-guests.md).

**os** `GuestOS | str | None` (default: None)

Guest operating system. Valid values: `"alpine"`, `"ubuntu"`, `"windows"`.

* For auto-config mode (no `image=`), selects the Linux distribution.
* For local images, **required** — tells Celesto which OS is inside the file. Must be `"windows"` for the local-image path in this release.
* For S3 images, must be omitted — the image manifest already records the OS.

**data\_dir** `Path | None` (default: None)

Override the default data directory for VM state storage.

**socket\_dir** `Path | None` (default: None)

Override the default socket directory.

**backend** `str | None` (default: None)

Runtime backend override. Options: `"firecracker"`, `"qemu"`, or `"auto"`.

**qemu\_machine** `Literal["auto", "microvm", "q35"]` (default: auto)

QEMU machine model. Keep `auto` for normal use so supported Linux guests use the faster `microvm` path.

**memory** `int | None` (default: None)

Guest memory in MiB for auto-config mode (when both `config` and `vm_id` are omitted). Default is 512 MiB.

**disk\_size** `int | None` (default: None)

Root filesystem size in MiB for auto-config mode. Default is 512 MiB. Minimum is 64 MiB.

**ssh\_user** `str` (default: root)

SSH user for command execution via the `run()` method. For Windows guests, pass the local Windows account name (for example `"Administrator"`) — `root` does not exist on Windows OpenSSH.

**ssh\_key\_path** `str | None` (default: None)

SSH private key path. If omitted, Celesto first tries default SSH auth, then falls back to `~/.smolvm/keys/id_ed25519`.

**ssh\_password** `str | None` (default: None)

SSH password. Use this when the guest only accepts password authentication — common for Windows qcow2s that ship with OpenSSH Server but no preinstalled key. When set, Celesto skips key-based auth so paramiko does not silently prefer a key over your password.

**comm\_channel** `Literal["ssh", "vsock"] | None` (default: None)

Host-to-guest control channel for `run()`, file transfer, and env var operations. Leave unset for auto-selection (vsock when the Celesto guest agent answers on a Linux QEMU host, otherwise SSH). Pass `"vsock"` to require vsock — Celesto raises if the agent does not answer instead of falling back. Pass `"ssh"` to force the SSH path. See [control channel](/docs/smolvm/concepts/control-channel.md) for details.

**internet\_settings** `InternetSettings | dict | None` (default: None)

Outbound access policy. See [Network controls](/docs/smolvm/features/network-controls.md) for supported QEMU and Firecracker combinations.

**mounts** `list[str] | None` (default: None)

Host folders to share with the sandbox. Each entry uses `HOST_PATH[:GUEST_PATH]`.

**writable\_mounts** `bool` (default: False)

Allow the sandbox to write through configured shared folders.

**callbacks** `list[Callback] | None` (default: None)

Callbacks that fire around each `run()` call. Use them to inspect, log, or block commands before they reach the guest. See [Run callbacks and safety hooks](/docs/smolvm/features/callbacks.md) for the full guide and the [Callback reference](/docs/smolvm/api/callbacks.md).

**state\_manager** `StateManagerProtocol | None` (default: None)

Inventory used to store and find sandbox state. Pass the same instance to create, reconnect, and restore operations that need to share an inventory.

### Raises

* `ValueError`: If both `config` and `vm_id` are provided, or if `memory`/`disk_size` are set outside auto-config mode.

## Class Methods

### from\_id

```python theme={null} theme={null}
@classmethod
Celesto.from_id(
    vm_id: str,
    *,
    data_dir: Path | None = None,
    socket_dir: Path | None = None,
    backend: str | None = None,
    ssh_user: str = "root",
    ssh_key_path: str | None = None,
    ssh_password: str | None = None,
    comm_channel: Literal["ssh", "vsock"] | None = None,
    state_manager: StateManagerProtocol | None = None,
) -> Celesto
```

Reconnect to an existing VM by ID through the same inventory that created it. Pass `ssh_password=` for Windows guests that use password-based SSH. Pass `comm_channel=` to override the host-to-guest control channel; see [control channel](/docs/smolvm/concepts/control-channel.md).

**vm\_id** `str` *required*

VM identifier to reconnect to.

**state\_manager** `StateManagerProtocol | None` *required*

Inventory that contains the sandbox. Reuse the exact state manager supplied when the sandbox was created.

**return** `Celesto`

A Celesto instance bound to the existing VM.

#### Raises

* `VMNotFoundError`: If no VM with this ID exists.
* `ValueError`: If `state_manager` is omitted.

### from\_image

```python theme={null} theme={null}
@classmethod
Celesto.from_image(
    image: BootImage,
    *,
    vm_id: str | None = None,
    name_prefix: str = "sbx",
    data_dir: Path | None = None,
    socket_dir: Path | None = None,
    state_manager: StateManagerProtocol | None = None,
    backend: str | None = None,
    arch: str | None = None,
    qemu_machine: Literal["auto", "microvm", "q35"] = "auto",
    vcpus: int = 1,
    memory_mb: int = 512,
    guest_os: GuestOS | str = GuestOS.ALPINE,
    network: Literal["tap", "slirp"] | None = None,
    port_forwards: list[PortForwardConfig | dict] | None = None,
    vsock: VsockConfig | dict | None = None,
    comm_channel: Literal["ssh", "vsock"] | None = None,
    disk_mode: Literal["isolated", "shared"] = "isolated",
    disk_size_mb: int | None = None,
    grow_filesystem: bool = False,
    ssh_user: str = "root",
    ssh_key_path: str | None = None,
    ssh_password: str | None = None,
    internet_settings: InternetSettings | dict | None = None,
    mounts: list[str] | None = None,
    writable_mounts: bool = False,
    callbacks: list[Callback] | None = None,
) -> Celesto
```

Launch a VM from a custom [`BootImage`](/docs/smolvm/guides/custom-images#describe-a-bootable-image) without writing a `VMConfig` by hand. The image supplies the rootfs, kernel, and boot arguments; `from_image` resolves the backend, architecture, and any missing base kernel, then applies the per-VM runtime knobs you pass in.

Use this when you have built a custom image (for example with `DockerRootfsBuilder`) and want a one-line launcher that still lets you tune memory, networking, port forwards, vsock, and the host-to-guest control channel.

**image** `BootImage` *required*

Image to boot. Direct-kernel images may omit `kernel_path` — Celesto downloads the matching base kernel automatically. Custom images without an SSH server can still boot, but command helpers such as `vm.run(...)` require an SSH-capable image or guest agent.

**vm\_id** `str | None` (default: None)

Custom VM identifier. Defaults to an auto-generated name using `name_prefix`.

**name\_prefix** `str` (default: sbx)

Prefix used when Celesto generates a `vm_id`.

**state\_manager** `StateManagerProtocol | None` (default: None)

Inventory used for the new sandbox. Pass the same instance to a later reconnect or snapshot restore.

**backend** `str | None` (default: None)

Runtime backend (`"firecracker"`, `"qemu"`, or `"libkrun"`). Defaults to the backend recorded on the image, otherwise normal auto-selection. Firmware-boot images require `"qemu"`.

Celesto's public guides focus on Firecracker and QEMU because they have the broadest current support.

**qemu\_machine** `Literal["auto", "microvm", "q35"]` (default: auto)

QEMU machine model. Keep `auto` for the fastest supported default.

**arch** `str | None` (default: None)

Guest architecture (`"amd64"` or `"arm64"`). Defaults to the image's recorded arch, otherwise the host arch.

**vcpus** `int` (default: 1)

Number of guest vCPUs.

**memory\_mb** `int` (default: 512)

Guest memory in MiB.

**guest\_os** `GuestOS | str` (default: GuestOS.ALPINE)

Guest OS hint used by Celesto's lifecycle helpers (`"alpine"`, `"ubuntu"`, or `"windows"`).

**network** `Literal["tap", "slirp"] | None` (default: None)

QEMU network mode. Use `"slirp"` to enable user-mode networking with `port_forwards`. Ignored for non-QEMU backends.

**port\_forwards** `list[PortForwardConfig | dict] | None` (default: None)

Host-to-guest port forwards. Only valid with `backend="qemu"` and `network="slirp"`.

**vsock** `VsockConfig | dict | None` (default: None)

Vsock configuration for host-to-guest control or custom services.

**comm\_channel** `Literal["ssh", "vsock"] | None` (default: None)

Host-to-guest control channel for `run()` and file transfers. See [control channel](/docs/smolvm/concepts/control-channel.md).

**disk\_mode** `Literal["isolated", "shared"]` (default: isolated)

Whether each VM gets its own per-VM disk overlay (`"isolated"`) or shares the base image (`"shared"`).

**disk\_size\_mb** `int | None` (default: None)

Target size in MiB for the per-VM disk. Celesto only grows the disk — pick a value at least as large as the image's current size. Requires `disk_mode="isolated"` (the default); shared base images are never resized. Works for both `raw-ext4` and `qcow2` rootfs formats.

**grow\_filesystem** `bool` (default: False)

After resizing the disk, grow the guest filesystem to fill it. Only supported for `raw-ext4` rootfs images and requires `e2fsprogs` (`e2fsck`, `resize2fs`) on the host. Leave `False` for qcow2 images and grow the filesystem from inside the guest instead.

**ssh\_user** `str` (default: root)

SSH user for `run()`. Ignored when the image is not SSH-capable.

**ssh\_key\_path** `str | None` (default: None)

SSH private key path.

**ssh\_password** `str | None` (default: None)

SSH password. Use this for images that ship password-only SSH.

**internet\_settings** `InternetSettings | dict | None` (default: None)

Outbound access policy. QEMU `off` works with the default network on macOS and Linux; `restricted` requires explicit TAP networking on Linux.

**return** `Celesto`

A Celesto instance bound to the new VM. Call `start()` (or use the context manager) to boot it.

#### Raises

* `ValueError`: If the requested backend, arch, network mode, or `port_forwards` are incompatible with the image (for example, `port_forwards` outside QEMU slirp, or a firmware image on Firecracker).
* `CelestoError`: If a disk resize is requested but cannot be honored — for example, `disk_mode="shared"`, `grow_filesystem=True` on a qcow2 image, a `disk_size_mb` smaller than the current disk, or `e2fsprogs` missing on the host.

#### Example

```python theme={null} theme={null}
from celesto import Celesto, DirectKernelBoot, DockerRootfsBuilder

builder = DockerRootfsBuilder(
    name="my-app",
    dockerfile="""
        FROM alpine:3.20
        RUN apk add --no-cache python3
        COPY init /init
        RUN chmod +x /init
    """,
    context={
        "init": "#!/bin/sh\nwhile true; do sleep 3600; done\n",
    },
)

image = builder.ensure(
    backend="qemu",
    arch="host",
    boot=DirectKernelBoot(root="/dev/vda", init="/init"),
)

with Celesto.from_image(image, memory_mb=1024, vcpus=2) as vm:
    print(f"Started {vm.vm_id}")
```

### browser

```python theme={null} theme={null}
@classmethod
Celesto.browser(
    *,
    headless: bool = True,
    session_id: str | None = None,
    backend: Literal["firecracker", "qemu", "libkrun", "auto"] = "auto",
    profile_id: str | None = None,
    persistent: bool = False,
    timeout_minutes: int = 30,
    viewport: BrowserViewport | dict[str, Any] | None = None,
    viewport_width: int = 1280,
    viewport_height: int = 720,
    record_video: bool = False,
    allow_downloads: bool = True,
    env_vars: dict[str, str] | None = None,
    workspace_mounts: list[WorkspaceMount] | None = None,
    memory_mb: int = 2048,
    disk_size_mb: int = 4096,
    data_dir: Path | None = None,
    socket_dir: Path | None = None,
    ssh_key_path: str | None = None,
    boot_timeout: float = 90.0,
    on_progress: Callable[[str], None] | None = None,
) -> DisplaySandboxProtocol
```

Start a Chromium browser inside a disposable sandbox. Use `headless=True` for a Chrome DevTools Protocol automation URL, or `headless=False` to also get a live viewer and VNC display URL. VNC means Virtual Network Computing, a standard way to view and control a remote screen.

**return** `DisplaySandboxProtocol`

A started browser sandbox with `cdp_url`, and with `viewer_url` plus `display_url` when `headless=False`.

See [Browser and desktop sandboxes](/docs/smolvm/api/browsersession.md) for the full option list and examples.

### desktop

```python theme={null} theme={null}
@classmethod
Celesto.desktop(
    *,
    session_id: str | None = None,
    backend: Literal["firecracker", "qemu", "libkrun", "auto"] = "auto",
    profile_id: str | None = None,
    persistent: bool = False,
    timeout_minutes: int = 30,
    viewport: BrowserViewport | dict[str, Any] | None = None,
    viewport_width: int = 1280,
    viewport_height: int = 720,
    record_video: bool = False,
    allow_downloads: bool = True,
    env_vars: dict[str, str] | None = None,
    workspace_mounts: list[WorkspaceMount] | None = None,
    memory_mb: int = 2048,
    disk_size_mb: int = 4096,
    data_dir: Path | None = None,
    socket_dir: Path | None = None,
    ssh_key_path: str | None = None,
    boot_timeout: float = 90.0,
    on_progress: Callable[[str], None] | None = None,
) -> DisplaySandboxProtocol
```

Start a full desktop display inside a disposable sandbox. Use `viewer_url` to open the desktop in your browser, or `display_url` for a VNC-compatible computer-use agent.

**return** `DisplaySandboxProtocol`

A started desktop sandbox with `viewer_url` and `display_url`.

See [Browser and desktop sandboxes](/docs/smolvm/api/browsersession.md) for desktop examples.

### from\_snapshot

```python theme={null} theme={null}
@classmethod
Celesto.from_snapshot(
    snapshot_id: str,
    *,
    data_dir: Path | None = None,
    socket_dir: Path | None = None,
    backend: str | None = None,
    resume_vm: bool = False,
    force: bool = False,
    ssh_user: str = "root",
    ssh_key_path: str | None = None,
    comm_channel: Literal["ssh", "vsock"] | None = None,
    state_manager: StateManagerProtocol | None = None,
) -> Celesto
```

Restore a snapshot and attach a facade to the restored VM.

**snapshot\_id** `str` *required*

The identifier of the snapshot to restore.

**resume\_vm** `bool` (default: False)

Resume the restored VM immediately. When False, the VM is restored in a paused state.

**force** `bool` (default: False)

Allow restoring a snapshot that was already restored before. By default, each snapshot can only be restored once.

**data\_dir** `Path | None` (default: None)

Override the default data directory.

**socket\_dir** `Path | None` (default: None)

Override the default socket directory.

**backend** `str | None` (default: None)

Runtime backend override.

**ssh\_user** `str` (default: root)

SSH user for command execution.

**ssh\_key\_path** `str | None` (default: None)

SSH private key path.

**comm\_channel** `Literal["ssh", "vsock"] | None` (default: None)

Host-to-guest command channel for the restored sandbox.

**state\_manager** `StateManagerProtocol | None` (default: None)

Inventory containing the snapshot. Reuse the state manager supplied to the workflow that created the snapshot.

**return** `Celesto`

A Celesto instance bound to the restored VM.

#### Raises

* `SnapshotNotFoundError`: If no snapshot with this ID exists.
* `CelestoError`: If the snapshot was already restored (use `force=True` to override).

## Lifecycle Methods

### start

```python theme={null} theme={null}
def start(self, boot_timeout: float = 30.0) -> Celesto
```

Start the VM. If the VM config contains `env_vars`, they are injected into the guest via SSH after boot completes.

**boot\_timeout** `float` (default: 30.0)

Maximum seconds to wait for boot to complete.

**return** `Celesto`

Returns `self` for method chaining.

#### Raises

* `CelestoError`: If `env_vars` is set but the image does not support SSH (missing `init=/init` in boot args).

### stop

```python theme={null} theme={null}
def stop(self, timeout: float = 3.0) -> Celesto
```

Stop the VM gracefully.

**timeout** `float` (default: 3.0)

Seconds to wait for graceful shutdown.

**return** `Celesto`

Returns `self` for method chaining.

### delete

```python theme={null} theme={null}
def delete(self) -> None
```

Delete the VM and release all resources.

### pause

```python theme={null} theme={null}
def pause(self) -> Celesto
```

Pause a running VM. The VM's memory and CPU state are frozen in place. Use `resume()` to continue execution.

**return** `Celesto`

Returns `self` for method chaining.

#### Raises

* `CelestoError`: If the VM is not in a pausable state (must be running).

### resume

```python theme={null} theme={null}
def resume(self) -> Celesto
```

Resume a paused VM. Execution continues from the exact point where it was paused.

**return** `Celesto`

Returns `self` for method chaining.

#### Raises

* `CelestoError`: If the VM is not paused.

### snapshot

```python theme={null} theme={null}
def snapshot(
    self,
    snapshot_id: str | None = None,
    *,
    snapshot_type: SnapshotType | str = SnapshotType.FULL,
    resume_source: bool = False,
) -> SnapshotInfo
```

Create a snapshot of the VM. The VM must be running or paused. If running, Celesto pauses it during snapshot creation unless `resume_source=True` is set.

**snapshot\_id** `str | None` (default: None)

Custom snapshot identifier. If omitted, Celesto generates one automatically (for example, `snap-my-vm-1717012345`). Must contain only lowercase letters, numbers, hyphens, and underscores.

**snapshot\_type** `SnapshotType | str` (default: SnapshotType.FULL)

What to save:

* `"full"` — complete disk copy plus memory and CPU state.
* `"diff"` — smaller disk artifact. QEMU diff snapshots need their backing image at restore time.
* `"disk"` — disk-only on QEMU; restores as a cold boot.

On Firecracker, Celesto captures memory and VM state for every snapshot type.

**resume\_source** `bool` (default: False)

Resume the source VM after snapshot creation. When False, the VM stays paused.

**return** `SnapshotInfo`

Metadata about the created snapshot, including file paths and timestamps.

#### Raises

* `SnapshotAlreadyExistsError`: If a snapshot with this ID already exists.
* `CelestoError`: If the VM is not in a snapshotable state, uses a Windows guest, uses shared disk mode, has extra drives, has workspace mounts, or is a QEMU raw disk created for filesystem growth.

## Command Execution Methods

### run

```python theme={null} theme={null}
def run(
    self,
    command: str,
    timeout: int = 30,
    shell: Literal["login", "raw"] = "login",
) -> CommandResult
```

Execute a command on the guest via SSH. Lazily creates an SSH client on first call and reuses it for subsequent invocations.

**command** `str` *required*

Shell command to execute on the guest.

**timeout** `int` (default: 30)

Maximum seconds to wait for the command to complete.

**shell** `Literal['login', 'raw']` (default: login)

Command execution mode:

* `"login"` (default): run via guest login shell
* `"raw"`: execute command directly with no shell wrapping

**return** `CommandResult`

Result object containing exit code, stdout, and stderr.

#### Raises

* `CelestoError`: If the VM is not running or has no network.
* `CommandExecutionUnavailableError`: If SSH is not available on the guest.
* `CommandBlockedError`: If an `on_pre_run` callback vetoes the command. Any other exception raised by a pre-run callback also propagates from `run()`.

### add\_callback

```python theme={null} theme={null}
def add_callback(self, callback: Callback) -> Celesto
```

Register a [`Callback`](/docs/smolvm/api/callbacks) on this sandbox after construction. Returns `self` so calls can be chained.

**callback** `Callback` *required*

A `Callback` instance to attach. Its hooks will fire on subsequent `run()` calls.

**return** `Celesto`

Returns `self` for method chaining.

#### Raises

* `TypeError`: If `callback` is not a `Callback` instance.

### wait\_for\_ssh

```python theme={null} theme={null}
def wait_for_ssh(self, timeout: float = 60.0) -> Celesto
```

Wait for SSH to become available on the guest.

**timeout** `float` (default: 60.0)

Maximum seconds to wait.

**return** `Celesto`

Returns `self` for method chaining.

#### Raises

* `OperationTimeoutError`: If SSH is not available within the timeout.
* `CelestoError`: If the VM is not running.

### ssh\_commands

```python theme={null} theme={null}
def ssh_commands(
    self,
    *,
    ssh_user: str | None = None,
    key_path: str | Path | None = None,
    public_host: str | None = None,
) -> dict[str, str]
```

Get ready-to-run SSH commands for this VM.

**ssh\_user** `str | None` (default: None)

SSH user override. Defaults to the instance's configured ssh\_user.

**key\_path** `str | Path | None` (default: None)

SSH key path override.

**public\_host** `str | None` (default: None)

Public hostname override for remote access.

**return** `dict[str, str]`

Dictionary mapping command names to ready-to-run SSH command strings.

## Environment Variable Methods

### set\_env\_vars

```python theme={null} theme={null}
def set_env_vars(
    self,
    env_vars: dict[str, str],
    *,
    merge: bool = True
) -> list[str]
```

Set environment variables on a running VM. Variables are persisted in `/etc/profile.d/smolvm_env.sh` and affect new SSH sessions/login shells.

**env\_vars** `dict[str, str]` *required*

Key/value pairs to set.

**merge** `bool` (default: True)

If True, merge with existing variables. If False, replace all variables.

**return** `list[str]`

Sorted list of variable names present after the update.

### unset\_env\_vars

```python theme={null} theme={null}
def unset_env_vars(self, keys: list[str]) -> dict[str, str]
```

Remove environment variables from a running VM.

**keys** `list[str]` *required*

Variable names to remove.

**return** `dict[str, str]`

Mapping of removed keys to their previous values.

### list\_env\_vars

```python theme={null} theme={null}
def list_env_vars(self) -> dict[str, str]
```

Return Celesto-managed environment variables for a running VM.

**return** `dict[str, str]`

Dictionary of environment variable names to values.

## Port Forwarding Methods

### expose\_local

```python theme={null} theme={null}
def expose_local(
    self,
    guest_port: int,
    host_port: int | None = None,
    *,
    guest_loopback: bool = False,
) -> int
```

Expose a guest TCP port on localhost only. Forwards `127.0.0.1:<host_port>` on the host to `<guest_ip>:<guest_port>` inside the VM.

**guest\_port** `int` *required*

Guest TCP port to expose (1-65535).

**host\_port** `int | None` (default: None)

Host localhost port. If omitted, an available port is automatically chosen.

**guest\_loopback** `bool` (default: False)

Route to the guest's `127.0.0.1` through an SSH tunnel. Use this only when the application listens on guest loopback instead of its network address.

**return** `int`

The host localhost port to connect to.

#### Raises

* `CelestoError`: If the VM is not running or has no network.
* `ValueError`: If port numbers are out of valid range (1-65535).

### unexpose\_local

```python theme={null} theme={null}
def unexpose_local(self, host_port: int, guest_port: int) -> Celesto
```

Remove a previously configured localhost-only port forward.

**host\_port** `int` *required*

Host localhost port (1-65535).

**guest\_port** `int` *required*

Guest TCP port (1-65535).

**return** `Celesto`

Returns `self` for method chaining.

## Properties

### vm\_id

```python theme={null} theme={null}
@property
def vm_id(self) -> str
```

The VM identifier.

### info

```python theme={null} theme={null}
@property
def info(self) -> VMInfo
```

Current VM runtime information (cached). Call `refresh()` to update from the state store.

### status

```python theme={null} theme={null}
@property
def status(self) -> VMState
```

Current VM lifecycle state (cached). Values: `CREATED`, `RUNNING`, `PAUSED`, `STOPPED`, `ERROR`.

### data\_dir

```python theme={null} theme={null}
@property
def data_dir(self) -> Path
```

Directory backing the VM state database and logs.

## Utility Methods

### get\_ip

```python theme={null} theme={null}
def get_ip(self) -> str
```

Return the guest IP address.

**return** `str`

The guest VM's IP address.

#### Raises

* `CelestoError`: If the VM has no network configuration.

### refresh

```python theme={null} theme={null}
def refresh(self) -> Celesto
```

Refresh cached VM info from the state store.

**return** `Celesto`

Returns `self` for method chaining.

### can\_run\_commands

```python theme={null} theme={null}
def can_run_commands(self) -> bool
```

Whether this VM config supports command execution via SSH. Command execution requires Celesto's SSH init flow, enabled by booting with `init=/init`.

**return** `bool`

True if SSH command execution is supported, False otherwise.

### close

```python theme={null} theme={null}
def close(self) -> None
```

Release underlying SDK resources for this facade instance.

## Async methods

Celesto provides async versions of lifecycle and command methods for use in async applications.

### async\_start

```python theme={null} theme={null}
async def async_start(self, boot_timeout: float = 30.0) -> Celesto
```

Async version of `start()`. Starts the VM without blocking the event loop.

### async\_stop

```python theme={null} theme={null}
async def async_stop(self, timeout: float = 3.0) -> Celesto
```

Async version of `stop()`.

### async\_run

```python theme={null} theme={null}
async def async_run(
    self,
    command: str,
    timeout: int = 30,
    shell: Literal["login", "raw"] = "login",
) -> CommandResult
```

Async version of `run()`. Executes a command on the guest without blocking.

### async\_wait\_for\_ssh

```python theme={null} theme={null}
async def async_wait_for_ssh(self, timeout: float = 60.0) -> Celesto
```

Async version of `wait_for_ssh()`.

### async\_create\_many

```python theme={null} theme={null}
@classmethod
async def async_create_many(
    cls,
    count: int,
    *,
    memory: int | None = None,
    disk_size: int | None = None,
    backend: str | None = None,
) -> list[Celesto]
```

Create multiple sandboxes concurrently. Each sandbox is auto-configured and started.

**count** `int` *required*

Number of sandboxes to create.

**memory** `int | None` (default: None)

Memory for each sandbox in MiB.

**disk\_size** `int | None` (default: None)

Disk size for each sandbox in MiB.

**return** `list[Celesto]`

List of started Celesto instances.

**Example:**

```python theme={null}
import asyncio
from celesto import Celesto

async def main():
    vms = await Celesto.async_create_many(3)
    for vm in vms:
        result = await vm.async_run("hostname")
        print(result.stdout.strip())
    for vm in vms:
        await vm.async_stop()
        vm.delete()

asyncio.run(main())
```

## Async context manager

Celesto also works as an async context manager:

```python theme={null}
import asyncio
from celesto import Celesto

async def main():
    async with Celesto() as vm:
        result = await vm.async_run("echo 'Hello from async'")
        print(result.stdout.strip())

asyncio.run(main())
```

## Context manager

Celesto implements the context manager protocol for automatic lifecycle management:

```python theme={null} theme={null}
with Celesto() as vm:
    # VM auto-starts on context entry
    result = vm.run("uname -r")
    print(result.stdout)
# VM auto-stops and auto-deletes on context exit
```

On context entry (`__enter__`):

* Auto-starts VMs created by this facade instance

On context exit (`__exit__`):

* Best-effort stop if the VM is running
* Auto-deletes only VMs created by this facade instance (not reconnected VMs)
* Releases all resources via `close()`

## Usage Examples

### Auto-Configuration Mode

Create an SSH-ready VM with default settings:

```python theme={null} theme={null}
from celesto import Celesto

with Celesto() as vm:
    result = vm.run("echo 'Hello from Celesto'")
    print(result.stdout.strip())
```

### Custom Configuration

Create a VM with specific resources:

```python theme={null} theme={null}
from celesto import Celesto

with Celesto(memory=1024, disk_size=1024) as vm:
    result = vm.run("free -m")
    print(result.stdout)
```

### Manual Lifecycle Management

```python theme={null} theme={null}
from celesto import Celesto, VMConfig
from pathlib import Path

config = VMConfig(
    vm_id="my-vm",
    vcpu_count=2,
    memory=512,
    kernel_path=Path("/path/to/kernel"),
    rootfs_path=Path("/path/to/rootfs"),
    boot_args="console=ttyS0 reboot=k panic=1 init=/init"
)

vm = Celesto(config)
vm.start()

result = vm.run("hostname")
print(result.stdout)

vm.stop()
vm.delete()
vm.close()
```

### Windows Guest

Boot a pre-installed Windows 11 `qcow2` image, run a PowerShell command, and upload a file. Requires a Linux host with KVM, the OVMF + `swtpm` packages installed, and an image with OpenSSH Server set up. See the [Windows guests guide](/docs/smolvm/guides/windows-guests.md) for prerequisites and limitations.

```python theme={null} theme={null}
from celesto import Celesto

with Celesto(
    os="windows",
    image="~/win11-vm/disk-baseline.qcow2",
    ssh_user="celesto",
    ssh_password="celesto",
    memory=4096,
) as vm:
    vm.wait_for_ssh()

    result = vm.run("Write-Output 'hello from windows'")
    print(result.stdout)  # 'hello from windows\r\n'

    vm.upload_file("./hello.ps1", "C:\\Users\\celesto\\hello.ps1")
```

On Windows guests, `vm.run(...)` executes the command in PowerShell, and `vm.upload_file(...)` accepts Windows-style destination paths (`C:\\...`, `C:/...`, or `/C:/...`).

### Reconnecting to Existing VM

```python theme={null} theme={null}
from celesto import Celesto

from pathlib import Path
from celesto.storage import MemoryStateManager

inventory = MemoryStateManager(Path(".smolvm-state"))
original = Celesto(state_manager=inventory)
original.start()
vm_id = original.vm_id
original.close()

# Reuse the same inventory when creating a new handle.
vm = Celesto.from_id(vm_id, state_manager=inventory)
result = vm.run("uptime")
print(result.stdout)
vm.close()
```

### Port Forwarding

```python theme={null} theme={null}
from celesto import Celesto

with Celesto() as vm:
    # Install and start a web server
    vm.run("apk add python3")
    vm.run("python3 -m http.server 8000 &")
    
    # Expose guest port 8000 on localhost
    host_port = vm.expose_local(guest_port=8000)
    print(f"Server available at http://localhost:{host_port}")
    
    # Access the server from host
    # ...
    
    # Clean up port forward
    vm.unexpose_local(host_port=host_port, guest_port=8000)
```

### Pause and Resume

```python theme={null} theme={null}
from celesto import Celesto

vm = Celesto()
vm.start()

# Run some setup
vm.run("echo 'setup complete'")

# Pause the VM to save resources
vm.pause()

# Resume when you need it again
vm.resume()
result = vm.run("echo 'back online'")
print(result.stdout.strip())

vm.stop()
vm.delete()
vm.close()
```

### Environment Variables

```python theme={null} theme={null}
from celesto import Celesto

with Celesto() as vm:
    # Set environment variables
    vm.set_env_vars({"API_KEY": "secret", "ENV": "production"})
    
    # List current variables
    env_vars = vm.list_env_vars()
    print(env_vars)  # {'API_KEY': 'secret', 'ENV': 'production'}
    
    # Variables persist across sessions
    result = vm.run("echo $API_KEY")
    print(result.stdout.strip())  # secret
    
    # Remove variables
    removed = vm.unset_env_vars(["API_KEY"])
    print(removed)  # {'API_KEY': 'secret'}
```


## Related topics

- [Callback hooks Python reference](/docs/smolvm/api/callbacks.md)
- [celesto windows](/docs/smolvm/cli/windows.md)
- [Managed agents SDK reference](/docs/cloud/managed-agents/reference.md)
- [Tool System](/docs/agentor/concepts/tools.md)
- [MCPAPIRouter](/docs/agentor/api/mcp/router.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.