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

# Sessions and execution modes

> Distinguish client workflow state from operations and live processes.

A session helps a client remember workflow state. It does not keep a sandbox VM or process alive after an operation ends.

## What each object retains

| Object | Retains | Does not retain |
| - | - | - |
| CLI session | Selected image, working directory, staged files, branches, and local history | VM, process memory, running services, or open connections |
| Python SDK session | The current image reference and latest command result; saved runs update the reference | Compute or a separately addressable live process |
| REST application state | Whatever operation IDs and image UUIDs the application records | Any implicit session supplied by the Sandboxes API |
| MCP client conversation | Client and server tool context, subject to the MCP integration | A VM after its operation ends |

A new command from a saved image always creates new execution.

## Choose an execution mode

| Need | Mode | Result |
| - | - | - |
| Final output from one bounded command | Await Python `run()`, call sync `run().wait()`, use `contree run`, or submit and poll REST | One operation and a terminal process result |
| Launch work and observe it later | REST submit; CLI `contree run -d` followed by `contree op wait OPERATION_ID`; MCP `run(wait=false)` | Operation ID for later status inspection |
| Progressive output with reconnection | REST SSE | Output and lifecycle events plus `Last-Event-Id` resumption |
| Send stdin or a signal to a separately addressed process in active work | REST additional-subprocess endpoints | Subprocess ID inside a parent operation |
| Familiar synchronous subprocess syntax | SDK 0.3.6 `popen()` wrapper | A local wrapper around one remote image execution |

The SDK `popen()` wrapper is not the REST additional-subprocess API. It does not attach a new child to an already-running operation.

## Python run patterns

Complete [Set up access](/sandboxes/start/set-up-access) and install `contree-sdk==0.3.6` as shown in the [Python quickstart](/sandboxes/start/python-quickstart). Each example runs `/bin/echo` so the execution mode is easy to compare. Use an image tag available in your project.

Place the async fragment inside the quickstart’s async `main()`, with its authenticated `client`. The synchronous examples can run as ordinary Python scripts.

Async SDK 0.3.6 prepares the request first and submits it when awaited:

```python theme={null}
image = await client.images.use("alpine:3.19", strict=True)
prepared = image.run(command="/bin/echo", args=["hello"], disposable=True)
result = await prepared
if result.exit_code != 0:
    raise RuntimeError(f"Command failed: {result.stderr}")
print(result.stdout, end="")
```

The synchronous client uses `wait()`:

```python theme={null}
from contree_sdk import ContreeSync

client = ContreeSync()
image = client.images.use("alpine:3.19", strict=True)
result = image.run(command="/bin/echo", args=["hello"], disposable=True).wait()
if result.exit_code != 0:
    raise RuntimeError(f"Command failed: {result.stderr}")
print(result.stdout, end="")
```

The synchronous subprocess-style wrapper supports the familiar `popen()` and `wait()` sequence in SDK 0.3.6:

```python theme={null}
from contree_sdk import ContreeSync

client = ContreeSync()
image = client.images.use("alpine:3.19", strict=True)
process = image.popen(["/bin/echo", "hello"], text=True)
process.wait()
if process.returncode != 0:
    raise RuntimeError(f"Command failed: {process.stderr}")
print(process.stdout, end="")
```

Each example prints:

```text theme={null}
hello
```

Set persistence explicitly in any `run()` call whose state matters. The SDK 0.3.6 session signature also defaults to `disposable=True`; session naming does not change that choice.

## Live processes

An additional subprocess can run only while its parent operation is active. It shares the parent VM, filesystem, resource budget, and lifetime. Use the REST endpoints to:

1. wait for an explicit parent readiness signal;
2. spawn the additional process and record its subprocess ID;
3. observe its output or send ordered stdin;
4. close stdin deliberately or send a signal; and
5. inspect both child and parent results.

A completed child does not create its own checkpoint. See [Run subprocesses and send input](/sandboxes/guides/run-subprocesses-and-send-input) for the bounded workflow.

## Continue

* [Choose an interface](/sandboxes/start/choose-an-interface)
* [Execution lifecycle](/sandboxes/concepts/execution-lifecycle)
* [Stream output and events](/sandboxes/guides/stream-output-and-events)
* [Run subprocesses and send input](/sandboxes/guides/run-subprocesses-and-send-input)
* [CLI sessions](/sandboxes/cli/tutorial/sessions)
* [Python session reference](/sandboxes/sdk/python_sdk/reference/session)
