Python Sandbox
The Python sandbox lets you deploy any Python function as a callable tool. The function runs in an isolated environment and can be used standalone or attached to an agent.
Setup
pip install aixplain
from aixplain import Aixplain
import inspect
import time
aix = Aixplain(api_key="YOUR_API_KEY")
Quick start
def add_numbers(a: int, b: int):
return a + b
script_tool = aix.Tool(
name=f"Addition Tool {int(time.time())}",
integration="688779d8bfb8e46c273982ca", # Python Sandbox
config={
"code": inspect.getsource(add_numbers),
"function_name": "add_numbers",
},
)
script_tool.save()
result = script_tool.run(data={"a": 4, "b": 6}, action="add_numbers")
print(result.data) # 10
Create a script tool
1. Define and extract the function
Use inspect.getsource() to capture the function source as a string:
def calculate_statistics(numbers: list):
import statistics
return {
"mean": statistics.mean(numbers),
"median": statistics.median(numbers),
"stdev": statistics.stdev(numbers) if len(numbers) > 1 else 0,
"count": len(numbers),
}
script_content = inspect.getsource(calculate_statistics)
To load from a file instead:
with open("my_function.py") as f:
script_content = f.read()
Function requirements:
Most legacy authoring rules have been relaxed — multi-line def signatures, short parameter names, default values, missing type hints, top-level imports, and zero-argument functions all work. The only hard constraints today are:
function_namemust exactly match a function defined incode. Helper functions in the same file are fine — only the one named byfunction_nameis registered as the tool- Do not use
boolparameters. The runtime serializer emits JSONtrue/false(lowercase), which then errors inside Python withNameError: name 'true' is not defined. Useint(0/1) instead until this is fixed - Avoid returning tuples or unpacking multiple values. Tuple returns round-trip as a string repr (e.g.
"(2, 3)") rather than structured data. Return adictorlistwhen you need more than one value - Return values must be JSON-serialisable (dicts, lists, strings, numbers)
Type hints are no longer enforced, but we still recommend them — they help the agent infer a clean tool schema and make the function easier to call correctly.
2. Save the tool
stats_tool = aix.Tool(
name=f"Statistics Calculator {int(time.time())}",
integration="688779d8bfb8e46c273982ca",
config={
"code": script_content,
"function_name": "calculate_statistics",
},
)
stats_tool.save()
| Config key | Required | Description |
|---|---|---|
code | ✅ | Complete function source as a string |
function_name | ✅ | Name of the function to expose — must match the definition in code |
3. Run the function
result = stats_tool.run(
data={"numbers": [10, 20, 30, 40, 50]},
action="calculate_statistics",
)
print(result.data)
Pass parameters as a dict with keys matching the function's argument names. If the tool has only one action, the action parameter can be omitted.
Examples
Text processing
def process_text(text: str, uppercase: str):
result = text.strip()
if uppercase == "True":
result = result.upper()
return {"original": text, "processed": result, "length": len(result)}
text_tool = aix.Tool(
name=f"Text Processor {int(time.time())}",
integration="688779d8bfb8e46c273982ca",
config={"code": inspect.getsource(process_text), "function_name": "process_text"},
)
text_tool.save()
result = text_tool.run(
data={"text": " hello world ", "uppercase": "True"},
action="process_text",
)
print(result.data)
Record filtering
def transform_records(records: list, filter_key: str, filter_value: str):
filtered = [r for r in records if r.get(filter_key) == filter_value]
return {
"total_input": len(records),
"total_output": len(filtered),
"filtered_records": filtered,
}
transform_tool = aix.Tool(
name=f"Record Transformer {int(time.time())}",
integration="688779d8bfb8e46c273982ca",
config={"code": inspect.getsource(transform_records), "function_name": "transform_records"},
)
transform_tool.save()
result = transform_tool.run(
data={
"records": [
{"id": 1, "category": "fruit", "name": "apple"},
{"id": 2, "category": "vegetable", "name": "carrot"},
{"id": 3, "category": "fruit", "name": "banana"},
],
"filter_key": "category",
"filter_value": "fruit",
},
action="transform_records",
)
print(result.data)
Error handling inside functions
Return errors as data rather than raising exceptions — the agent can reason about them:
def safe_divide(a: float, b: float):
if b == 0:
return {"error": "Cannot divide by zero", "result": None}
return {"result": a / b, "error": None}
Use with agents
# replaces: LangChain @tool decorator + StructuredTool + manual schema definition
# Python function becomes an agent tool directly; schema inferred automatically
def calculate_discount(price: float, discount_percent: float):
discount = price * (discount_percent / 100)
return {
"original_price": price,
"discount_amount": round(discount, 2),
"final_price": round(price - discount, 2),
}
discount_tool = aix.Tool(
name=f"Discount Calculator {int(time.time())}",
integration="688779d8bfb8e46c273982ca",
config={"code": inspect.getsource(calculate_discount), "function_name": "calculate_discount"},
)
discount_tool.save()
agent = aix.Agent(
name="Pricing Assistant",
description="Calculates prices with discounts.",
instructions="Use the discount calculator tool to compute final prices. Always show the original price, discount amount, and final price.",
tools=[discount_tool],
)
agent.save()
response = agent.run("What's the final price for a $100 item with 20% off?")
print(response.data.output)
Troubleshooting
function_name not found
Confirm the value in config["function_name"] matches the function name in config["code"] exactly. Print script_content to verify what was captured.
Import errors in the sandbox
Only Python standard library modules and commonly available packages are supported. Top-level import statements now work — you no longer need to move every import inside the function body — but if a package is unavailable in the sandbox runtime you'll see an ImportError at call time.
Boolean parameters errors out with NameError: name 'true' is not defined
The runtime serializer encodes bool arguments as JSON true/false (lowercase), which Python then rejects. Use an int (0/1) parameter and coerce inside the function as a workaround.
inspect.getsource() fails
The function must be defined in a file, not typed interactively in a REPL. In notebooks, define the function and call inspect.getsource() in the same cell.
Type or serialisation errors Parameters and return values must be JSON-serialisable. Convert custom objects to dicts, lists, or primitives before returning.