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

# Python Code

> Executes a `handler(input)` function in a secure Firecracker sandbox and returns markdown plus structured data.

Executes a `handler(input)` function in a secure Firecracker sandbox and returns markdown plus structured data. Display name **"Python Code"**. Off by default — enable it in the agent's Tools panel.

This is **not** how you render HTML in the task feed.

## When to use it (vs `app_tool` vs `custom_interface` vs `generate_file`)

| Need | Tool |
| - | - |
| Compute, transform, call an API, or produce markdown/data from code | `python_code_tool` |
| Interactive mini-app in the task feed (iframe, buttons, writes back) | `app_tool` |
| Read-only HTML view of prior step outputs | `custom_interface` |
| A downloadable file (CSV/XLSX/PDF/HTML/MD/DOCX/JSON) | `generate_file` |

handler(input) must return `{'markdown': str, 'data': any}`. That markdown is what the feed shows — not HTML. There is no flag to "render as HTML". If the user wants a scorecard or interactive widget in the feed, use `app_tool` (interactive) or `custom_interface` (display-only).

## Authentication and enablement

No OAuth. Runs in the platform sandbox (HTTP calls capped, time/memory limited). Off by default.

## Inputs

* `python_code` (required for the base tool; injected from bindings on a configured tool): a `handler(input)` function.
* `input` (required): extra parameters for the handler. **Never pass `"input": {}`** if the instructions mention parameters. Task variables (`VAR_1`, `VAR_2`, …) are auto-injected — read them as `input['VAR_1']`; do not put them in `input` yourself.
* `input['STATE']` (auto-injected, when task state is on for the agent): the task state — the agent's output schema filled so far, merged across tool calls, with human corrections applied. Every field is present (`None` when not found yet) and every table row carries every column. Read it as `input['STATE']['fields']['total']` or loop `input['STATE']['tables']['table1']`. It is a snapshot taken when the step is created, read with the saved mappings only; do not put `STATE` in `input` yourself.

Python syntax: `None` / `True` / `False`, not JSON `null` / `true` / `false`.

## Output

Structured result with `output` (the handler return), `prints` (stdout), and optional `artifacts` from `save_artifact(name, content)`. The feed renders `output.markdown`.

## Limits and side effects

* Sandbox: bounded CPU, memory, and outbound HTTP. The outbound budget counts HTTP sent
  through the `requests` library. Raw-socket protocols such as SSH and SFTP are not counted
  against it and are not restricted to the allowed-host list.
* `save_artifact` uploads files the user can download; call it once per file.
* Configured-tool code is stored in bindings and not shown as a per-run input on later runs.

## Expected errors

* Empty `input` when parameters were required — the handler then has nothing to work with.
* Handler does not return `{'markdown', 'data'}` — treat as a contract violation and fix the return.
* Sandbox timeout / HTTP budget exceeded.


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