# Sandbox Persistence
<subtitle>Support pausing and resuming sandbox state, preserving memory runtime data and file system state.</subtitle>

## Environment Setup

Before using the SDK, please ensure that the `AGENTBOX_API_KEY` environment variable is configured.

>
> You can obtain your API key from the [Console API Keys page](https://console.ucloud.cn/modelverse/experience/api-keys).

```bash
export AGENTBOX_API_KEY=your_api_key
```

> Sandbox persistence is currently in public beta.

Sandbox persistence allows you to pause a running sandbox and resume it to exactly the same state when needed.

Unlike simple disk snapshots, UCloud Sandbox persistence includes **memory state**. This means all running processes, loaded variables, open file handles, etc. will be preserved exactly as they were.

## State Transitions

Understanding state changes of sandboxes at different lifecycle stages helps manage resources more precisely.

*   **Running**: Sandbox is running normally and can execute code. This is the default state after creation.
*   **Paused**: Sandbox execution is suspended, physical resources are released, but memory and disk state are encrypted and saved.
*   **Killed**: Sandbox is completely deleted, all related resources and data are cleaned up. This state is irreversible.

### State Operation Example

```python
from ucloud_sandbox import Sandbox

# 1. Start in Running state
sandbox = Sandbox.create()

# 2. Pause sandbox (Running → Paused)
sandbox.beta_pause()

# 3. Resume sandbox (Paused → Running)
# Using connect method to connect to sandbox with specific ID will automatically trigger resume
same_sbx = Sandbox.connect(sandbox.sandbox_id)

# 4. Completely destroy (Running/Paused → Killed)
same_sbx.kill()
```

## Pause and Resume Details

### Pause Sandbox
When you call `beta_pause()`, the sandbox will immediately freeze all processes and persist the state.

```python
from ucloud_sandbox import Sandbox

sbx = Sandbox.create()
print(f"Sandbox {sbx.sandbox_id} is running.")

# Perform some operations, such as defining variables or running services
# ...

# Pause and save state
sbx.beta_pause()
print("Sandbox state saved and paused.")
```

### Resume Sandbox (Resume/Connect)
Resume sandbox through `Sandbox.connect(id)`. The restored environment is exactly the same as the moment it was paused.

```python
from ucloud_sandbox import Sandbox

# Connect and resume paused sandbox
# If sandbox is running, directly establish connection
sbx = Sandbox.connect("your-sandbox-id")
print("Connected and resumed.")
```

## Managing Paused Sandboxes

### List Query
You can filter out all sandboxes currently in paused state to prevent resource deadlock.

```python
from ucloud_sandbox import Sandbox, SandboxQuery, SandboxState

# Query all paused sandboxes
paginator = Sandbox.list(query=SandboxQuery(state=[SandboxState.PAUSED]))
sandboxes = paginator.next_items()

for sbx in sandboxes:
    print(f"Paused Sandbox ID: {sbx.sandbox_id}")
```

### Manual Cleanup
If you no longer need a paused sandbox, be sure to destroy it.

```python
# Destroy through instance
sbx.kill()

# Or destroy directly through ID
Sandbox.kill("your-sandbox-id")
```

## Auto Pause (Beta)

>
> **Note**: Auto pause feature is currently only available through `Sandbox.beta_create()`.

You can configure sandboxes to automatically enter paused state instead of being directly destroyed when inactive (after timeout), to balance response speed and cost.

```python
from ucloud_sandbox import Sandbox

# Create sandbox with auto pause enabled
sandbox = Sandbox.beta_create(
    auto_pause=True,       # Automatically enter paused state after timeout
    timeout=10 * 60        # Set 10-minute inactive timeout
)
```

## Beta Phase Limitations and Notes

*   **Time Consumption**: Pause operation takes approximately 4 seconds per GB of memory; resume operation is usually completed within 1 second.
*   **Network**: During sandbox pause, its exposed public URLs will be inaccessible, and connected clients will disconnect. Connection needs to be re-established after resume.
*   **Validity Period**: Paused state is retained for a maximum of **30 days**. Beyond this period, the system will automatically clean up data, and attempting to resume will throw `NotFoundException`.