docs/sdk/python/ssh.mdx
Reach a running sandbox over SSH: open a native in-process SSH client, run exec requests, attach an interactive shell, transfer files over SFTP, or stand up a reusable server endpoint that serves connections over stdin/stdout. See SSH for usage flows.
<p className="msb-label" id="typical-flow">Typical flow</p>from microsandbox import Sandbox
async with await Sandbox.create("api", image="python") as sb:
client = await sb.ssh().open_client() # 1. open an SSH client
out = await client.exec("python -V") # 2. run a command
print(out.stdout_text)
await client.close() # 3. close the session
def ssh() -> SandboxSshOps
client = await sb.ssh().open_client()
Return the SSH namespace for this sandbox. The namespace holds the SSH client and server helpers; nothing connects until you call open_client() or prepare_server(). This method is synchronous; the helpers it returns are async.
SSH namespace for a sandbox, obtained from sb.ssh(). SSH is only supported on local sandboxes.
async def open_client(
*,
user: str = "root",
term: str | None = None,
sftp: bool = True,
) -> SshClient
client = await sb.ssh().open_client(user="app", term="xterm-256color")
out = await client.exec("uname -a")
Connect a native in-process SSH client to this sandbox. Generates an ephemeral client and host key pair, stands up an internal server bound to an in-memory stream, and authenticates over public key.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>user</code><span className="msb-type">str</span></div> <div className="msb-param-desc">SSH login user. Default <code>"root"</code>.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>term</code><span className="msb-type">str | None</span></div> <div className="msb-param-desc">Terminal name for interactive sessions. Defaults to <code>$TERM</code>.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>sftp</code><span className="msb-type">bool</span></div> <div className="msb-param-desc">Enable or disable SFTP on the internal server. Default <code>True</code>.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#sshclient">SshClient</a></div> <div className="msb-param-desc">Connected SSH client session.</div> </div> </div>async def prepare_server(
*,
host_key_path: str | os.PathLike[str] | None = None,
authorized_keys_path: str | os.PathLike[str] | None = None,
user: str | None = None,
sftp: bool = True,
) -> SshServer
server = await sb.ssh().prepare_server(
authorized_keys_path="/home/me/.ssh/authorized_keys",
user="app",
sftp=False,
)
await server.serve_connection()
Prepare a reusable SSH server endpoint for this sandbox. Loads or creates the host key and resolves authorized keys, falling back to the default authorized-keys file when no path is given. The returned SshServer serves one connection over this process's stdin/stdout.
A connected, native in-process SSH client session, obtained from ssh.open_client().
async def exec(command: str, *, tty: bool = False) -> SshOutput
out = await client.exec("echo hello")
print(f"exit {out.status}: {out.stdout_text}")
Run an SSH exec request and collect stdout, stderr, and the exit status. The command runs through the sandbox's configured shell. When tty=True a PTY is allocated and stderr is folded into stdout.
async def attach(
*,
term: str | None = None,
detach_keys: str | None = None,
) -> int
code = await client.attach(term="xterm-256color", detach_keys="ctrl-p,ctrl-q")
print(f"shell exited with {code}")
Attach the local terminal to an interactive SSH shell. Requests a PTY sized to the current terminal, puts the terminal into raw mode, forwards keystrokes, and returns when the shell exits or the detach key sequence is typed.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>term</code><span className="msb-type">str | None</span></div> <div className="msb-param-desc">Terminal name for the shell. Defaults to <code>$TERM</code>.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>detach_keys</code><span className="msb-type">str | None</span></div> <div className="msb-param-desc">Detach key sequence, e.g. <code>"ctrl-p,ctrl-q"</code>.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">int</span></div> <div className="msb-param-desc">Shell exit code (128 if terminated by signal).</div> </div> </div>async def sftp() -> SftpClient
sftp = await client.sftp()
await sftp.write("/tmp/hello.txt", b"hi")
data = await sftp.read("/tmp/hello.txt")
Open an SFTP client session over this SSH connection. Requests the sftp subsystem and returns a high-level session for reading, writing, and listing files inside the guest.
async def close() -> None
await client.close()
Close this native SSH client session. Sends a disconnect and aborts the internal server task.
A reusable SSH server endpoint for a sandbox, obtained from ssh.prepare_server().
async def serve_connection() -> None
server = await sb.ssh().prepare_server()
await server.serve_connection()
Serve one SSH transport over this process's stdin/stdout. Runs the SSH handshake and session loop to completion, returning when the connection closes. Use this to bridge an SSH connection over the parent process's standard streams.
def close() -> None
server.close()
Release this prepared server endpoint. This method is synchronous.
SSH namespace for a sandbox.
| Method | Returns | Description |
|---|---|---|
open_client() | SshClient | (async) Open a client. |
prepare_server() | SshServer | (async) Prepare a server endpoint. |
Native in-process SSH client session.
| Method | Returns | Description |
|---|---|---|
exec(command, *, tty=False) | SshOutput | (async) Run a command. |
attach(*, term=None, detach_keys=None) | int | (async) Interactive shell. |
sftp() | SftpClient | (async) Open an SFTP session. |
close() | None | (async) Close the session. |
Reusable SSH server endpoint for a sandbox.
| Method | Returns | Description |
|---|---|---|
serve_connection() | None | (async) Serve one connection over stdin/stdout. |
close() | None | Release the prepared endpoint. |
High-level SFTP client session over an SSH connection. All methods are async.
| Method | Returns | Description |
|---|---|---|
| read(path) | bytes | Read a file into memory. |
| write(path, data) | None | Write a file, creating or truncating it. |
| mkdir(path) | None | Create a directory. |
| remove_file(path) | None | Remove a file. |
| remove_dir(path) | None | Remove an empty directory. |
| rename(old_path, new_path) | None | Rename a file or directory. |
| real_path(path) | str | Resolve a path to its canonical absolute form. |
| read_link(path) | str | Read a symlink target. |
| symlink(target, link_path) | None | Create a symlink. |
| close() | None | Close the SFTP session. |
Output from an SSH exec request.
| Property | Type | Description |
|---|---|---|
| status | int | Exit status code. |
| success | bool | Whether the command exited successfully. |
| stdout_text | str | Stdout as UTF-8 text. |
| stderr_text | str | Stderr as UTF-8 text. |
| stdout_bytes | bytes | Stdout as raw bytes. |
| stderr_bytes | bytes | Stderr as raw bytes. |