n8n Code Python
Expert guidance for writing Python in n8n Code nodes.
Based on n8n-skills by Romuald Członkowski
Python Code Node Basics
n8n supports Python in Code nodes with some differences from JavaScript.
Run Once for All Items
# Access all input items
items = _input.all()
# Process and return
return [{"json": {**item.json, "processed": True}} for item in items]
Run Once for Each Item
# Access current item
data = _input.item.json
# Return single item
return {"json": {**data, "processed": True}}
Accessing Data
Current Node Input
# All items
items = _input.all()
# First item
first = _input.first()
# Current item (in "each item" mode)
current = _input.item
# JSON data
data = _input.first().json
Execution Context
# Note: Limited compared to JavaScript
# Access via items or hardcoded values
Common Patterns
Transform All Items
items = _input.all()
return [
{
"json": {
"id": item.json["id"],
"name": item.json["name"].upper(),
"processed": True
}
}
for item in items
]
Filter Items
items = _input.all()
return [
{"json": item.json}
for item in items
if item.json.get("status") == "active"
]
Aggregate Data
items = _input.all()
total = sum(item.json.get("amount", 0) for item in items)
count = len(items)
return [{
"json": {
"total": total,
"count": count,
"average": total / count if count > 0 else 0
}
}]
Group By
from collections import defaultdict
items = _input.all()
grouped = defaultdict(list)
for item in items:
key = item.json.get("category", "unknown")
grouped[key].append(item.json)
return [
{"json": {"category": k, "items": v, "count": len(v)}}
for k, v in grouped.items()
]
JSON Parsing
import json
items = _input.all()
return [
{
"json": {
"parsed": json.loads(item.json.get("rawData", "{}"))
}
}
for item in items
]
Error Handling
import json
items = _input.all()
results = []
for item in items:
try:
parsed = json.loads(item.json.get("rawData", "{}"))
results.append({"json": {"success": True, "data": parsed}})
except Exception as e:
results.append({"json": {"success": False, "error": str(e)}})
return results
Date/Time Handling
from datetime import datetime, timedelta
# Current time
now = datetime.now()
# Parse ISO date
date = datetime.fromisoformat("2024-01-15T10:30:00")
# Format
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
# Add/subtract
next_week = now + timedelta(days=7)
yesterday = now - timedelta(days=1)
# Return with dates
return [{
"json": {
"now": now.isoformat(),
"formatted": formatted,
"nextWeek": next_week.isoformat()
}
}]
Working with Pandas
⚠️ Note: pandas may not be available in all n8n installations. Check your environment.
import pandas as pd
items = _input.all()
# Convert to DataFrame
data = [item.json for item in items]
df = pd.DataFrame(data)
# Process with pandas
df["total"] = df["price"] * df["quantity"]
df_grouped = df.groupby("category").agg({"total": "sum"}).reset_index()
# Convert back to n8n format
return [{"json": row} for row in df_grouped.to_dict(orient="records")]
Webhook Data Access
CRITICAL: Webhook data is under .body:
# ❌ Wrong
message = _input.first().json.get("message")
# ✅ Correct - webhook data is in body
body = _input.first().json.get("body", {})
message = body.get("message")
headers = _input.first().json.get("headers", {})
query = _input.first().json.get("query", {})
Available Libraries
Standard Python libraries typically available:
json- JSON parsingdatetime- Date/time handlingre- Regular expressionscollections- Data structuresmath- Mathematical functionsbase64- Encodinghashlib- Hashing
import json
import re
import hashlib
from datetime import datetime
from collections import defaultdict
# Use hashlib
hash_value = hashlib.sha256(data.encode()).hexdigest()
# Use regex
matches = re.findall(r"\d+", text)
Common Mistakes
1. Wrong Return Format
# ❌ Wrong - must return list of dicts with "json" key
return {"name": "John"}
# ✅ Correct
return [{"json": {"name": "John"}}]
2. Using dot notation for dict access
# ❌ Wrong - Python dicts use brackets
name = item.json.name
# ✅ Correct
name = item.json["name"]
# or safer:
name = item.json.get("name", "default")
3. Not Handling Missing Keys
# ❌ Wrong - KeyError if missing
value = item.json["optional_field"]
# ✅ Correct
value = item.json.get("optional_field", "default")
4. Returning dict instead of list
# ❌ Wrong in "all items" mode
return {"json": {"result": "data"}}
# ✅ Correct - always return list
return [{"json": {"result": "data"}}]
Python vs JavaScript in n8n
| Feature | Python | JavaScript |
|---|---|---|
| Input access | _input |
$input |
| Node access | Limited | $node["Name"] |
| Env vars | Limited | $env.VAR |
| Async/await | No | Yes |
| Libraries | Standard + limited | Luxon, Lodash |
Best Practices
- Always return list of
{"json": {...}}dicts - Use
.get()for safe dict access - Handle exceptions with try/except
- Import at top of code block
- Test with simple data first
- Access webhook data via
.body
Quick Reference
| Need | Code |
|---|---|
| All items | _input.all() |
| First item | _input.first() |
| Current item | _input.item (each mode) |
| Item JSON | item.json |
| Dict value | item.json.get("key", default) |
| Webhook body | item.json.get("body", {}) |
| Return item | {"json": {...}} |
| Return many | [{"json": {...}}, ...] |
Based on n8n-skills by Romuald Członkowski • Adapted for Moltbot by fazer.ai
Source: fazer-ai/moltbot-skill-n8n — distributed by TomeVault.