> ## Documentation Index
> Fetch the complete documentation index at: https://microsanbox-staging-appcypher-sdk-runtime-bootstrap.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# SSH

> Python SDK - SSH API reference

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](/sandboxes/ssh) for usage flows.

## Sandbox

#### <span className="msb-recv">sb.</span><span className="msb-hn">ssh()</span>

```python theme={null}
def ssh() -> SandboxSshOps
```

<Accordion title="Example">
  ```python theme={null}
  client = await sb.ssh().open_client()
  ```
</Accordion>

Return the SSH namespace for this sandbox. The namespace holds the SSH client and server helpers; nothing connects until you call [`open_client()`](#ssh-open_client) or [`prepare_server()`](#ssh-prepare_server). This method is synchronous; the helpers it returns are async.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sandboxsshops">SandboxSshOps</a></div>
    <div className="msb-param-desc">SSH namespace for this sandbox.</div>
  </div>
</div>

## SandboxSshOps

<p className="msb-backref">Returned by <a href="#sb-ssh">sb.ssh()</a></p>

SSH operations for a sandbox.

#### <span className="msb-recv">ssh.</span><span className="msb-hn">open\_client()</span>

```python theme={null}
async def open_client(
    *,
    user: str = "root",
    term: str | None = None,
    sftp: bool = True,
    inactivity_timeout: float | None = None,
) -> SshClient
```

<Accordion title="Example">
  ```python theme={null}
  client = await sb.ssh().open_client(user="app", term="xterm-256color")
  out = await client.exec("uname -a")
  ```
</Accordion>

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 className="msb-param">
    <div className="msb-param-key"><code>inactivity\_timeout</code><span className="msb-type">float | None</span></div>
    <div className="msb-param-desc">Disconnect after this many seconds without SSH traffic. <code>0</code> disables the timeout; <code>None</code> inherits the global setting.</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>

#### <span className="msb-recv">ssh.</span><span className="msb-hn">prepare\_server()</span>

<Tooltip tip="On microsandbox cloud, serving works when you supply explicit host-key and authorized-key material; the convenience defaults are local-only."><span className="msb-badge-limited">Limited on cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

```python theme={null}
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,
    inactivity_timeout: float | None = None,
) -> SshServer
```

<Accordion title="Example">
  ```python theme={null}
  server = await sb.ssh().prepare_server(
      authorized_keys_path="/home/me/.ssh/authorized_keys",
      user="app",
      sftp=False,
  )
  await server.serve_connection()
  ```
</Accordion>

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`](#sshserver) serves one connection over this process's stdin/stdout.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>host\_key\_path</code><span className="msb-type">str | os.PathLike\[str] | None</span></div>
    <div className="msb-param-desc">Override the host private key path.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>authorized\_keys\_path</code><span className="msb-type">str | os.PathLike\[str] | None</span></div>
    <div className="msb-param-desc">Override the authorized-keys path.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>user</code><span className="msb-type">str | None</span></div>
    <div className="msb-param-desc">Override the guest user used for exec requests.</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. Default <code>True</code>.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>inactivity\_timeout</code><span className="msb-type">float | None</span></div>
    <div className="msb-param-desc">Disconnect after this many seconds without SSH traffic. <code>0</code> disables the timeout; <code>None</code> inherits the global setting.</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="#sshserver">SshServer</a></div>
    <div className="msb-param-desc">Reusable SSH server endpoint.</div>
  </div>
</div>

## SshClient

<p className="msb-backref">Returned by <a href="#ssh-open_client">ssh.open\_client()</a></p>

Native in-process SSH client session.

A connected, native in-process SSH client session, obtained from [`ssh.open_client()`](#ssh-open_client).

#### <span className="msb-recv">client.</span><span className="msb-hn">exec()</span>

```python theme={null}
async def exec(command: str, *, tty: bool = False) -> SshOutput
```

<Accordion title="Example">
  ```python theme={null}
  out = await client.exec("echo hello")
  print(f"exit {out.status}: {out.stdout_text}")
  ```
</Accordion>

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.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>command</code><span className="msb-type">str</span></div>
    <div className="msb-param-desc">Command string sent through SSH.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>tty</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">Request a PTY for the exec channel. Default <code>False</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="#sshoutput">SshOutput</a></div>
    <div className="msb-param-desc">Captured output and exit status.</div>
  </div>
</div>

#### <span className="msb-recv">client.</span><span className="msb-hn">attach()</span>

```python theme={null}
async def attach(
    *,
    term: str | None = None,
    detach_keys: str | None = None,
) -> int
```

<Accordion title="Example">
  ```python theme={null}
  code = await client.attach(term="xterm-256color", detach_keys="ctrl-p,ctrl-q")
  print(f"shell exited with {code}")
  ```
</Accordion>

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>

#### <span className="msb-recv">client.</span><span className="msb-hn">sftp()</span>

```python theme={null}
async def sftp() -> SftpClient
```

<Accordion title="Example">
  ```python theme={null}
  sftp = await client.sftp()
  await sftp.write("/tmp/hello.txt", b"hi")
  data = await sftp.read("/tmp/hello.txt")
  ```
</Accordion>

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.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#sftpclient">SftpClient</a></div>
    <div className="msb-param-desc">SFTP client session.</div>
  </div>
</div>

#### <span className="msb-recv">client.</span><span className="msb-hn">close()</span>

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

<Accordion title="Example">
  ```python theme={null}
  await client.close()
  ```
</Accordion>

Close this native SSH client session. Sends a disconnect and aborts the internal server task.

## SshServer

<p className="msb-backref">Returned by <a href="#ssh-prepare_server">ssh.prepare\_server()</a></p>

Reusable SSH server endpoint for a sandbox.

A reusable SSH server endpoint for a sandbox, obtained from [`ssh.prepare_server()`](#ssh-prepare_server).

#### <span className="msb-recv">server.</span><span className="msb-hn">serve\_connection()</span>

```python theme={null}
async def serve_connection() -> None
```

<Accordion title="Example">
  ```python theme={null}
  server = await sb.ssh().prepare_server()
  await server.serve_connection()
  ```
</Accordion>

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.

#### <span className="msb-recv">server.</span><span className="msb-hn">close()</span>

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

<Accordion title="Example">
  ```python theme={null}
  server.close()
  ```
</Accordion>

Release this prepared server endpoint. This method is synchronous.

## SftpClient

<p className="msb-backref">Returned by <a href="#client-sftp">client.sftp()</a></p>

High-level SFTP client session over an SSH connection. All methods are async.

#### <span className="msb-recv">sftp.</span><span className="msb-hn">read()</span>

```python theme={null}
read(path)
```

Read a file into memory.

<p className="msb-label">Returns</p>

`bytes`

#### <span className="msb-recv">sftp.</span><span className="msb-hn">write()</span>

```python theme={null}
write(path, data)
```

Write a file, creating or truncating it.

#### <span className="msb-recv">sftp.</span><span className="msb-hn">mkdir()</span>

```python theme={null}
mkdir(path)
```

Create a directory.

#### <span className="msb-recv">sftp.</span><span className="msb-hn">remove\_file()</span>

```python theme={null}
remove_file(path)
```

Remove a file.

#### <span className="msb-recv">sftp.</span><span className="msb-hn">remove\_dir()</span>

```python theme={null}
remove_dir(path)
```

Remove an empty directory.

#### <span className="msb-recv">sftp.</span><span className="msb-hn">rename()</span>

```python theme={null}
rename(old_path, new_path)
```

Rename a file or directory.

#### <span className="msb-recv">sftp.</span><span className="msb-hn">real\_path()</span>

```python theme={null}
real_path(path)
```

Resolve a path to its canonical absolute form.

<p className="msb-label">Returns</p>

`str`

#### <span className="msb-recv">sftp.</span><span className="msb-hn">read\_link()</span>

```python theme={null}
read_link(path)
```

Read a symlink target.

<p className="msb-label">Returns</p>

`str`

#### <span className="msb-recv">sftp.</span><span className="msb-hn">symlink()</span>

```python theme={null}
symlink(target, link_path)
```

Create a symlink.

#### <span className="msb-recv">sftp.</span><span className="msb-hn">close()</span>

```python theme={null}
close()
```

Close the SFTP session.

## Types

### SshOutput

<p className="msb-backref">Returned by <a href="#client-exec">client.exec()</a></p>

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.                     |
