Skip to Content

Python tools

A Python tool runs a sandboxed Python handler you write in the Python Handler Editor. You reach it on the Implementation step of the Create a tool wizard by choosing the Native Python target and entering a Handler Name.

💡

Click Fullscreen to open the full Python Handler Editor with an insert sidebar (Variables, Functions, Config) and a Quick Reference panel.

The handler signature

Your code must define a single async handler with this exact signature:

async def handler(input, ctx=None): # your logic here return {"success": True, "result": ...}

The editor validates this as you type and shows a Valid or Invalid badge. Common validation messages:

  • Handler must be async: use "async def handler(...)"
  • Missing required function: async def handler(input, ctx=None)
  • Handler must accept two parameters: handler(input, ctx=None)

It also warns (without blocking) if the parameters aren’t named input and ctx, or if you don’t return a dict with a success key.

The Python Handler Editor with the code editor, validity badge, and toolbar buttons

Reading inputs and context

  • Inputs — the parameters you defined in Step 3 arrive in input (e.g. input["user_id"]). Validate them with is None checks.
  • Context — the ctx object exposes subscription_id, project_id, user_id, and config.
  • Config templates — reference secrets as {{config.xxx}}; they’re auto-detected and required as project secrets. See Configuration & secrets.
⚠️

On remote executors, ctx["db"], ctx["llm"], and ctx["config"] are not available. Use {{config.xxx}} templates for secrets when the execution location is Remote.

Tool chaining

A Python handler can call other project tools through the pre-injected tools object:

MethodPurpose
tools.call(...)Invoke another tool
tools.list_available()List callable tools
tools.get_tool_info(...)Inspect a tool
tools.get_call_log()Review calls made during this execution

The sandbox

Handlers run in a restricted sandbox. Only an allow-list of packages can be imported — including math, json, re, datetime, httpx, jwt, base64, hashlib, uuid, PyPDF2, pdfplumber, openpyxl, python-docx, pillow, and others. The Quick Reference panel lists the full set.

🚨

os, sys, subprocess, socket, and file-system modules are not available in the sandbox. Any import outside the allow-list is blocked.

Generate code with AI

Click AI Generate to scaffold a handler from a description. The dialog (“Describe what this tool should do”) produces code that follows the sandbox standards: a proper async def handler(input, ctx) signature, safe imports only, input validation, try/except error handling, and structlog-based logging. Your defined input parameters and chainable tools are passed to the generator automatically.

Other toolbar actions: Reset (restore the standard template), copy, and expand/collapse.

The AI Generate Handler dialog with a description field and standards checklist

Test the handler

Click Test to run the handler in the sandbox against sample input. The Test Output panel shows a Success or Failed status with duration, the returned value (“Handler returned:”), and any logs. On failure, expand Show Traceback for the full error.

The Python test terminal showing a successful run with returned output

Common issues

  • Invalid handler signature — must be exactly async def handler(input, ctx=None).
  • Import blocked — the package isn’t on the allow-list; check the Quick Reference panel.
  • Works locally, fails remotely — you’re using ctx["db"]/ctx["llm"]/ctx["config"] on a remote executor. Switch to {{config.xxx}} templates or set Execution Location to Local.
  • KeyError on an input — the parameter is optional or missing; guard with is None checks.