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

# Run Python Code with run_code() in Wrenn

> Use capsule.run_code() to execute Python cells and capture results, logs, and errors. Supports streaming callbacks for real-time output.

`run_code()` submits a Python cell to the capsule's persistent Jupyter kernel and returns once execution completes. The return value is an `Execution` object that contains all output the cell produced — expression values, printed text, and any exception that was raised.

## The Execution object

`run_code(code)` returns an `Execution` instance with the following fields:

| Field               | Type                     | Description                                                              |
| ------------------- | ------------------------ | ------------------------------------------------------------------------ |
| `results`           | `list[Result]`           | Rich outputs from the cell — charts, images, expression values.          |
| `logs`              | `Logs`                   | Captured stream output. `.stdout: list[str]` and `.stderr: list[str]`.   |
| `error`             | `ExecutionError \| None` | Populated when the cell raised an exception.                             |
| `execution_count`   | `int \| None`            | Jupyter cell execution counter (`[N]` in a notebook).                    |
| `text` *(property)* | `str \| None`            | `text/plain` of the main `execute_result` — the last expression's value. |

`result.logs.stdout` and `result.logs.stderr` are lists of string chunks, one per kernel `stream` message. Join them with `"".join(result.logs.stdout)` to get the full output.

## Error handling

When code raises an exception, `run_code()` does not raise a Python exception in your calling code. Instead, it populates `result.error` with an `ExecutionError` object.

```python theme={null}
from wrenn.code_interpreter import Capsule

with Capsule(wait=True) as capsule:
    result = capsule.run_code("1 / 0")

    if result.error:
        print(result.error.name)       # "ZeroDivisionError"
        print(result.error.value)      # "division by zero"
        print(result.error.traceback)  # full traceback string
```

The `ExecutionError` fields are:

| Field       | Type  | Description                                       |
| ----------- | ----- | ------------------------------------------------- |
| `name`      | `str` | Exception class name, e.g. `"ZeroDivisionError"`. |
| `value`     | `str` | Exception message.                                |
| `traceback` | `str` | Full traceback as a single string.                |

<Note>
  Errors in the executed code populate `result.error` — they do not raise exceptions in your calling code. Always check `result.error` when you need to handle failures.
</Note>

## Streaming callbacks

If you want to receive output as it arrives rather than waiting for the cell to finish, pass callback functions to `run_code()`.

```python theme={null}
with Capsule(wait=True) as capsule:
    capsule.run_code(
        """
import time
for i in range(5):
    print(f"step {i}")
    time.sleep(0.5)
""",
        on_stdout=lambda text: print("stdout:", text, end=""),
        on_stderr=lambda text: print("stderr:", text, end=""),
        on_result=lambda r: print("result:", r.formats()),
        on_error=lambda err: print(f"error: {err.name}: {err.value}"),
    )
```

The available callbacks are:

| Parameter   | Called when                                                     |
| ----------- | --------------------------------------------------------------- |
| `on_result` | A rich output is produced (`execute_result` or `display_data`). |
| `on_stdout` | A stdout chunk arrives from the kernel.                         |
| `on_stderr` | A stderr chunk arrives from the kernel.                         |
| `on_error`  | The cell raises an exception.                                   |

`run_code()` still returns the complete `Execution` object after the cell finishes, even when you use callbacks. The callbacks and the return value contain the same data.
