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

# Run Python

> Execute Python code from an agent with argv-list execution — no shell, no re-tokenisation

`run_python` runs a Python snippet for an agent and returns its output. Code is passed to `subprocess.run` as an argv list (`[sys.executable, "-c", code]`), so the source is preserved verbatim — no shell, no re-tokenisation — identically on POSIX and Windows.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.code.tools import run_python

agent = Agent(
    name="Python Runner",
    instructions="Run short Python snippets and report the output.",
    tools=[run_python],
)
agent.start("Print the sum of the first 10 squares")
```

The user asks the agent to compute something; the agent runs the snippet as an argv list and returns the captured output.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    U[📋 Code snippet] --> R[🐍 run_python]
    R --> A[🔧 argv: sys.executable -c code]
    A --> O[✅ stdout / exit code]

    classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff

    class U input
    class R,A process
    class O output
```

> [!NOTE]
>
> Code is executed via `subprocess.run([sys.executable, "-c", code])` — no shell, no re-tokenisation. Multi-line snippets, backslashes, and mixed quotes are preserved exactly as passed, identically on POSIX and Windows. The return shape matches `execute_command`.

## Quick Start

**1. Give an agent the tool**

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.code.tools import run_python

agent = Agent(
    name="Python Runner",
    instructions="Run Python snippets and report the output.",
    tools=[run_python],
)
agent.start("Compute 2 ** 20 and print it")
```

**2. Call it directly**

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code.tools import run_python

result = run_python("print('hello from python')")
print(result["stdout"])   # hello from python
print(result["exit_code"])  # 0
```

**3. Verify verbatim source is preserved**

Snippets with newlines, backslashes, and mixed quotes that used to break under shell quoting now run intact:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code.tools import run_python

result = run_python(r'''
import json
data = {"path": "C:\\Users\\alice", "note": "she said \"hi\""}
print(json.dumps(data))
''')
# → prints the intact JSON without shell mangling on either OS
```

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant Agent
    participant RunPython as run_python

    User->>Agent: Run this Python
    Agent->>RunPython: code snippet
    RunPython->>RunPython: subprocess.run([sys.executable, "-c", code])
    RunPython-->>Agent: {stdout, stderr, exit_code, success}
    Agent-->>User: Result
```

Passing an argv list means the operating system hands your exact `code` string to Python as a single argument. There is no intermediate shell to expand `$VAR`, collapse quotes, or re-split on whitespace — so the caller's source arrives byte-for-byte.

### Before / after

| Snippet feature | Old shell-string path | argv-list path |
| - | - | - |
| Newlines | Re-tokenised, often mangled | Preserved verbatim |
| Backslashes (`C:\Users\...`) | Escaped/expanded by the shell | Preserved verbatim |
| Mixed single/double quotes | Broke quoting, could error | Preserved verbatim |
| POSIX vs Windows | Diverged | Identical behaviour |

***

## Return Shape

`run_python` returns the same dictionary shape as `execute_command`:

| Key | Type | Description |
| - | - | - |
| `success` | `bool` | `True` when the exit code is `0` |
| `exit_code` | `int` | Process exit code |
| `stdout` | `str` | Captured standard output |
| `stderr` | `str` | Captured standard error |

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code.tools import run_python

result = run_python("import sys; sys.stderr.write('warn\\n'); print('ok')")
result["success"]    # True
result["stdout"]     # "ok\n"
result["stderr"]     # "warn\n"
```

***

## Best Practices

> [accordion] Use raw strings for backslash-heavy code
>
> Wrap Windows paths or regex-heavy snippets in `r'''...'''` so your own Python source doesn't consume the backslashes before `run_python` ever sees them.

> [accordion] Gate it behind approval for untrusted agents
>
> `run_python` executes arbitrary code. Pair it with [Approval](https://praison.ai/docs/features/approval.md) so a human confirms each snippet on untrusted routes.

> [accordion] Set a timeout for long snippets
>
> Pass `timeout=<seconds>` to bound execution; the default is `60` seconds.

> [accordion] Prefer run\_python over hand-building a shell command
>
> Building `python -c "..."` strings yourself re-introduces the quoting bugs this tool fixes. Pass the code to `run_python` and let the argv list carry it.

***

## Related

> [card] [Shell Tools](https://praison.ai/docs/tools/shell_tools.md)
>
> `execute_command` and process tools for shell-level tasks.

> [card] [Approval](https://praison.ai/docs/features/approval.md)
>
> Require human approval before an agent runs code.

> [card] [Protected Paths](https://praison.ai/docs/features/protected-paths.md)
>
> Block agents from touching sensitive files.

> [card] [Code Execution with Tools](https://praison.ai/docs/features/code-execution-with-tools.md)
>
> Let generated code call back into your registered tools.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.