# How the CodeInterpreter SDK Handles Stateful Code Execution Sessions

> Explore how the CodeInterpreter SDK manages stateful code execution. Learn how REPL processes in isolated sandboxes persist variables and imports across calls for seamless development.

- Repository: [Alibaba/OpenSandbox](https://github.com/alibaba/OpenSandbox)
- Tags: internals
- Published: 2026-03-08

---

**The CodeInterpreter SDK maintains stateful code execution sessions by spawning persistent language-specific REPL processes inside an isolated sandbox, allowing variables and imports to persist across multiple `run` calls through a unique context identifier.**

The **alibaba/OpenSandbox** project provides a secure, containerized environment for executing arbitrary code through its CodeInterpreter SDK. Unlike stateless execution models that reset after each script, this SDK enables **stateful code execution sessions** where variables, function definitions, and imported modules remain available across successive code submissions. This architecture is essential for building interactive coding assistants and iterative data analysis workflows.

## Architecture of Stateful Sessions

The SDK implements a layered architecture that keeps session state inside the sandbox rather than the client SDK.

### Core Components

| Layer | Responsibility | Key Classes |
|-------|----------------|-------------|
| **Sandbox** | Manages the isolated container, filesystem, commands, metrics and lifecycle. | `opensandbox.sync.sandbox.SandboxSync` (sync) / `opensandbox.sandbox.Sandbox` (async) |
| **Adapter Factory** | Creates concrete service clients that communicate with the `execd` daemon inside the sandbox. | `code_interpreter.sync.adapters.factory.AdapterFactorySync` / `code_interpreter.adapters.factory.AdapterFactory` |
| **Code Service** | Provides the public API for execution contexts and code runs via `create_context`, `run`, and `interrupt` methods. | `code_interpreter.services.code.Codes` (async) / `code_interpreter.sync.services.code.CodesSync` (protocol) |
| **Code Interpreter** | Public entry point exposing sandbox services plus the `codes` service for stateful execution. | `code_interpreter.code_interpreter.CodeInterpreter` (async) / `code_interpreter.sync.code_interpreter.CodeInterpreterSync` |

### State Persistence Mechanism

According to the source code in [`sdks/code-interpreter/python/src/code_interpreter/sync/code_interpreter.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/code-interpreter/python/src/code_interpreter/sync/code_interpreter.py) (lines 34-46 and 134-146), state is maintained **inside the sandbox** through a language-specific REPL session. When `CodesSync.create_context` is invoked, the `execd` daemon spawns a persistent process (e.g., a Python interpreter) that remains alive for the lifetime of the context.

Subsequent calls to `CodesSync.run` (lines 92-110 in [`sdks/code-interpreter/python/src/code_interpreter/sync/services/code.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/code-interpreter/python/src/code_interpreter/sync/services/code.py)) include the context identifier, routing code to the existing REPL instance. This design ensures that variables assigned in earlier executions remain accessible in later runs.

## Execution Lifecycle

The stateful session follows a three-phase lifecycle managed through the `Codes` service protocol.

### Creating an Execution Context

To initiate a stateful session, the SDK creates a context object that wraps a running REPL. In [`code_interpreter/sync/services/code.py`](https://github.com/alibaba/OpenSandbox/blob/main/code_interpreter/sync/services/code.py) (lines 58-70), the `create_context` method generates a unique `CodeContextSync` containing an `id` and `language` field. This request triggers the sandbox's `execd` daemon to launch the appropriate language runtime on `DEFAULT_EXECD_PORT` (defined in [`opensandbox/constants.py`](https://github.com/alibaba/OpenSandbox/blob/main/opensandbox/constants.py)).

### Running Code with State Preservation

Once established, the context enables persistent execution. The `run` method accepts a `context` parameter containing the session ID. As implemented in the async counterpart ([`code_interpreter/code_interpreter.py`](https://github.com/alibaba/OpenSandbox/blob/main/code_interpreter/code_interpreter.py), lines 72-88), the adapter factory builds a REST/SSE client that streams code to the persistent REPL and returns an `Execution` object containing stdout, stderr, and result values.

### Interrupting Executions

Long-running operations can be terminated without destroying the session state. The `interrupt` method (defined in the `CodesSync` protocol) sends a termination signal to the specific execution while leaving the underlying REPL process intact. This allows subsequent `run` calls to continue using preserved variables.

## Implementation Examples

The SDK provides both synchronous and asynchronous interfaces for stateful execution.

### Synchronous Session Management

The following example demonstrates variable persistence across multiple executions using the blocking API:

```python
from opensandbox.sync.sandbox import SandboxSync
from code_interpreter.sync.code_interpreter import CodeInterpreterSync
from code_interpreter.models.code_sync import SupportedLanguageSync

# 1️⃣ Create a sandbox

sandbox = SandboxSync.create("python:3.11")

# 2️⃣ Wrap it with a code‑interpreter

interpreter = CodeInterpreterSync.create(sandbox)

# 3️⃣ Create a persistent context (stateful REPL)

ctx = interpreter.codes.create_context(SupportedLanguageSync.PYTHON)

# 4️⃣ First run – defines a variable

interpreter.codes.run("x = 42", context=ctx)

# 5️⃣ Second run – re‑uses the same variable

result = interpreter.codes.run("print(f'value = {x}')", context=ctx)
print(result.logs.stdout)   # → "value = 42"

# Cleanup

sandbox.kill()
sandbox.close()

```

### Asynchronous Session Management

For concurrent applications, the async API provides identical stateful semantics:

```python
import asyncio
from opensandbox.sandbox import Sandbox
from code_interpreter.code_interpreter import CodeInterpreter
from code_interpreter.models.code import SupportedLanguage

async def demo():
    sandbox = await Sandbox.create("python:3.11")
    interpreter = await CodeInterpreter.create(sandbox)

    ctx = await interpreter.codes.create_context(SupportedLanguage.PYTHON)
    await interpreter.codes.run("counter = 0", context=ctx)

    for i in range(3):
        exec_res = await interpreter.codes.run(
            "counter += 1\nprint(counter)", context=ctx
        )
        print(exec_res.logs.stdout.strip())   # 1, then 2, then 3

    await sandbox.kill()
    await sandbox.close()

asyncio.run(demo())

```

## Key Source Files

The stateful execution logic is distributed across these critical files in the alibaba/OpenSandbox repository:

- [`sdks/code-interpreter/python/src/code_interpreter/sync/code_interpreter.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/code-interpreter/python/src/code_interpreter/sync/code_interpreter.py) – Sync entry point that creates `CodesSync` and exposes the `codes` property (lines 34-46, 134-146).
- [`sdks/code-interpreter/python/src/code_interpreter/code_interpreter.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/code-interpreter/python/src/code_interpreter/code_interpreter.py) – Async entry point mirroring the sync design (lines 72-88).
- [`sdks/code-interpreter/python/src/code_interpreter/sync/services/code.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/code-interpreter/python/src/code_interpreter/sync/services/code.py) – Protocol defining context lifecycle operations including `create_context`, `run`, and `interrupt` (lines 58-70, 92-110).
- [`sdks/code-interpreter/python/src/code_interpreter/models/code_sync.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/code-interpreter/python/src/code_interpreter/models/code_sync.py) – Data models for `CodeContextSync` and execution results.
- [`sdks/code-interpreter/python/src/code_interpreter/adapters/factory.py`](https://github.com/alibaba/OpenSandbox/blob/main/sdks/code-interpreter/python/src/code_interpreter/adapters/factory.py) – Factory for building REST/SSE clients that communicate with the `execd` daemon.

## Summary

- **Stateful sessions** are implemented through persistent REPL processes spawned inside the sandbox container, not in the client SDK.
- **Execution contexts** (`CodeContextSync`/`CodeContext`) maintain unique identifiers that route code to specific running language runtimes.
- The **`Codes` service protocol** provides `create_context`, `run`, and `interrupt` methods to manage session lifecycle and execution flow.
- Both **synchronous** (`CodeInterpreterSync`) and **asynchronous** (`CodeInterpreter`) APIs support variable preservation across multiple `run` invocations.
- State persists until the context is explicitly deleted or the sandbox is terminated.

## Frequently Asked Questions

### What is a stateful code execution session?

A stateful code execution session maintains memory of previous operations, allowing variables, function definitions, and imported libraries to persist across separate code submissions. In the CodeInterpreter SDK, this is achieved by keeping a language-specific REPL process running inside the sandbox throughout the session lifetime.

### How does the CodeInterpreter SDK preserve state between executions?

The SDK preserves state by creating a **context** that maps to a persistent REPL process inside the sandbox. When you call `create_context`, the `execd` daemon launches a language runtime (e.g., Python) that remains active. Subsequent `run` calls reference this context ID, directing code to the same process where previous variables remain in scope.

### Can I interrupt a running execution without losing the session state?

Yes. The `interrupt` method (available in both `CodesSync` and `Codes` protocols) terminates a specific long-running execution by signaling the `execd` daemon, but it leaves the underlying REPL process intact. This allows the context to remain valid for future `run` calls with all previous state preserved.

### What programming languages support stateful sessions in the SDK?

The SDK supports stateful sessions for any language implemented in the `SupportedLanguage` enumeration. The examples above demonstrate Python (`SupportedLanguageSync.PYTHON`), but the architecture supports multiple languages provided the sandbox contains the appropriate REPL runtime and the `execd` daemon has a corresponding handler.