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

# Python

> Run custom Python code for advanced logic, data processing, and computations

The **Python** node lets you write and execute custom Python code within your flow. Use it when built-in nodes aren't enough — complex data transformations, math, string parsing, conditional logic, or anything that's easier to express in code.

## When to Use It

* Complex data transformations that go beyond what Transform can do
* Parsing unstructured text (CSV, XML, regex extraction)
* Mathematical computations or aggregations
* Building dynamic objects with loops and conditionals
* Encoding/decoding data (Base64, URL encoding, hashing)
* Any logic that's simpler to write in code than to wire with nodes

## Configuration

Write your Python code directly in the node's code editor. Your code has access to the data from previous nodes and must return a result.

### Input

Data from previous nodes is available through the **input** variable — a dictionary containing the output of every upstream node:

```python theme={null}
# Access data from a previous node (ID: 1, label: "Fetch Users")
users = input["1_Fetch Users"]["body"]["data"]

# Access form data
name = input["1_Form"]["form_data"]["name"]
```

### Output

Your code must return a value using the `output` variable. This becomes the Python node's output that downstream nodes can reference:

```python theme={null}
# Simple value
output = {"status": "processed", "count": len(users)}

# Transformed list
output = [{"name": u["name"], "email": u["email"]} for u in users]
```

## Examples

> [accordion] Filter and transform a list
>
> ```python theme={null}
> users = input["1_API"]["body"]["users"]
>
> # Filter to active users and extract relevant fields
> active_users = [
>     {
>         "name": f"{u['first_name']} {u['last_name']}",
>         "email": u["email"],
>         "role": u.get("role", "member")
>     }
>     for u in users
>     if u.get("active") is True
> ]
>
> output = {
>     "users": active_users,
>     "total": len(active_users)
> }
> ```

> [accordion] Parse a CSV string
>
> ```python theme={null}
> import csv
> import io
>
> csv_text = input["1_Request"]["body"]["csv_data"]
> reader = csv.DictReader(io.StringIO(csv_text))
> records = [row for row in reader]
>
> output = {
>     "records": records,
>     "count": len(records)
> }
> ```

> [accordion] Aggregate and compute
>
> ```python theme={null}
> orders = input["1_Fetch Orders"]["body"]["orders"]
>
> total_revenue = sum(o["amount"] for o in orders)
> avg_order = total_revenue / len(orders) if orders else 0
> high_value = [o for o in orders if o["amount"] > 500]
>
> output = {
>     "total_revenue": round(total_revenue, 2),
>     "average_order": round(avg_order, 2),
>     "high_value_count": len(high_value),
>     "order_count": len(orders)
> }
> ```

> [accordion] Build a dynamic payload
>
> ```python theme={null}
> form = input["1_Form"]["form_data"]
>
> # Build different payloads based on form input
> if form.get("type") == "bug":
>     output = {
>         "channel": "#bugs",
>         "priority": "high",
>         "message": f"Bug report from {form['name']}: {form['description']}"
>     }
> else:
>     output = {
>         "channel": "#feedback",
>         "priority": "normal",
>         "message": f"Feedback from {form['name']}: {form['description']}"
>     }
> ```

> [accordion] String parsing with regex
>
> ```python theme={null}
> import re
>
> text = input["1_Webhook"]["body"]["message"]
>
> # Extract all email addresses from text
> emails = re.findall(r'[\w.+-]+@[\w-]+\.[\w.]+', text)
>
> # Extract invoice numbers (pattern: INV-XXXX)
> invoices = re.findall(r'INV-\d+', text)
>
> output = {
>     "emails": emails,
>     "invoices": invoices
> }
> ```

> [accordion] Date and time operations
>
> ```python theme={null}
> from datetime import datetime, timedelta
>
> created = input["1_Record"]["body"]["created_at"]
> created_dt = datetime.fromisoformat(created)
>
> output = {
>     "created": created,
>     "days_ago": (datetime.utcnow() - created_dt).days,
>     "is_recent": (datetime.utcnow() - created_dt).days < 7,
>     "expiry": (created_dt + timedelta(days=30)).isoformat()
> }
> ```

## Available Libraries

The Python node runs in a sandboxed environment with access to Python's standard library, including:

* `json` — JSON parsing and serialization
* `re` — Regular expressions
* `datetime` — Date and time operations
* `math` — Mathematical functions
* `csv` — CSV reading and writing
* `io` — String I/O
* `hashlib` — Hashing (MD5, SHA256, etc.)
* `base64` — Base64 encoding/decoding
* `urllib.parse` — URL encoding/decoding
* `collections` — Useful data structures

> [!WARNING]
>
> External packages (like `requests` or `pandas`) are not available. For HTTP calls, use a Request node before or after the Python node. For data manipulation, Python's built-in capabilities are sufficient for most use cases.

## Error Handling

If your Python code raises an exception, the node's **failure path** fires. The error message is available to downstream nodes on the failure path.

Write defensive code when working with data that might be missing or malformed:

```python theme={null}
users = input.get("1_API", {}).get("body", {}).get("users", [])

if not users:
    output = {"error": "No users found", "count": 0}
else:
    output = {"count": len(users), "first": users[0]["name"]}
```

> [!TIP]
>
> Use `print()` statements for debugging. Print output appears in the run logs, which you can view from the flow's run history.


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