n8n-code-python

安装量: 804
排名: #1567

安装

npx skills add https://github.com/czlonkowski/n8n-skills --skill n8n-code-python

Python Code Node (Beta)

Expert guidance for writing Python code in n8n Code nodes.

⚠️ Important: JavaScript First

Recommendation: Use JavaScript for 95% of use cases. Only use Python when:

You need specific Python standard library functions You're significantly more comfortable with Python syntax You're doing data transformations better suited to Python

Why JavaScript is preferred:

Full n8n helper functions ($helpers.httpRequest, etc.) Luxon DateTime library for advanced date/time operations No external library limitations Better n8n documentation and community support Quick Start

Basic template for Python Code nodes

items = _input.all()

Process data

processed = [] for item in items: processed.append({ "json": { **item["json"], "processed": True, "timestamp": datetime.now().isoformat() } })

return processed

Essential Rules Consider JavaScript first - Use Python only when necessary Access data: _input.all(), _input.first(), or _input.item CRITICAL: Must return [{"json": {...}}] format CRITICAL: Webhook data is under _json["body"] (not _json directly) CRITICAL LIMITATION: No external libraries (no requests, pandas, numpy) Standard library only: json, datetime, re, base64, hashlib, urllib.parse, math, random, statistics Mode Selection Guide

Same as JavaScript - choose based on your use case:

Run Once for All Items (Recommended - Default)

Use this mode for: 95% of use cases

How it works: Code executes once regardless of input count Data access: _input.all() or _items array (Native mode) Best for: Aggregation, filtering, batch processing, transformations Performance: Faster for multiple items (single execution)

Example: Calculate total from all items

all_items = _input.all() total = sum(item["json"].get("amount", 0) for item in all_items)

return [{ "json": { "total": total, "count": len(all_items), "average": total / len(all_items) if all_items else 0 } }]

Run Once for Each Item

Use this mode for: Specialized cases only

How it works: Code executes separately for each input item Data access: _input.item or _item (Native mode) Best for: Item-specific logic, independent operations, per-item validation Performance: Slower for large datasets (multiple executions)

Example: Add processing timestamp to each item

item = _input.item

return [{ "json": { **item["json"], "processed": True, "processed_at": datetime.now().isoformat() } }]

Python Modes: Beta vs Native

n8n offers two Python execution modes:

Python (Beta) - Recommended Use: _input, _json, _node helper syntax Best for: Most Python use cases Helpers available: _now, _today, _jmespath() Import: from datetime import datetime

Python (Beta) example

items = _input.all() now = _now # Built-in datetime object

return [{ "json": { "count": len(items), "timestamp": now.isoformat() } }]

Python (Native) (Beta) Use: _items, _item variables only No helpers: No _input, _now, etc. More limited: Standard Python only Use when: Need pure Python without n8n helpers

Python (Native) example

processed = []

for item in _items: processed.append({ "json": { "id": item["json"].get("id"), "processed": True } })

return processed

Recommendation: Use Python (Beta) for better n8n integration.

Data Access Patterns Pattern 1: _input.all() - Most Common

Use when: Processing arrays, batch operations, aggregations

Get all items from previous node

all_items = _input.all()

Filter, transform as needed

valid = [item for item in all_items if item["json"].get("status") == "active"]

processed = [] for item in valid: processed.append({ "json": { "id": item["json"]["id"], "name": item["json"]["name"] } })

return processed

Pattern 2: _input.first() - Very Common

Use when: Working with single objects, API responses

Get first item only

first_item = _input.first() data = first_item["json"]

return [{ "json": { "result": process_data(data), "processed_at": datetime.now().isoformat() } }]

Pattern 3: _input.item - Each Item Mode Only

Use when: In "Run Once for Each Item" mode

Current item in loop (Each Item mode only)

current_item = _input.item

return [{ "json": { **current_item["json"], "item_processed": True } }]

Pattern 4: _node - Reference Other Nodes

Use when: Need data from specific nodes in workflow

Get output from specific node

webhook_data = _node["Webhook"]["json"] http_data = _node["HTTP Request"]["json"]

return [{ "json": { "combined": { "webhook": webhook_data, "api": http_data } } }]

See: DATA_ACCESS.md for comprehensive guide

Critical: Webhook Data Structure

MOST COMMON MISTAKE: Webhook data is nested under ["body"]

❌ WRONG - Will raise KeyError

name = _json["name"] email = _json["email"]

✅ CORRECT - Webhook data is under ["body"]

name = _json["body"]["name"] email = _json["body"]["email"]

✅ SAFER - Use .get() for safe access

webhook_data = _json.get("body", {}) name = webhook_data.get("name")

Why: Webhook node wraps all request data under body property. This includes POST data, query parameters, and JSON payloads.

See: DATA_ACCESS.md for full webhook structure details

Return Format Requirements

CRITICAL RULE: Always return list of dictionaries with "json" key

Correct Return Formats

✅ Single result

return [{ "json": { "field1": value1, "field2": value2 } }]

✅ Multiple results

return [ {"json": {"id": 1, "data": "first"}}, {"json": {"id": 2, "data": "second"}} ]

✅ List comprehension

transformed = [ {"json": {"id": item["json"]["id"], "processed": True}} for item in _input.all() if item["json"].get("valid") ] return transformed

✅ Empty result (when no data to return)

return []

✅ Conditional return

if should_process: return [{"json": processed_data}] else: return []

Incorrect Return Formats

❌ WRONG: Dictionary without list wrapper

return { "json": {"field": value} }

❌ WRONG: List without json wrapper

return [{"field": value}]

❌ WRONG: Plain string

return "processed"

❌ WRONG: Incomplete structure

return [{"data": value}] # Should be {"json": value}

Why it matters: Next nodes expect list format. Incorrect format causes workflow execution to fail.

See: ERROR_PATTERNS.md #2 for detailed error solutions

Critical Limitation: No External Libraries

MOST IMPORTANT PYTHON LIMITATION: Cannot import external packages

What's NOT Available

❌ NOT AVAILABLE - Will raise ModuleNotFoundError

import requests # ❌ No import pandas # ❌ No import numpy # ❌ No import scipy # ❌ No from bs4 import BeautifulSoup # ❌ No import lxml # ❌ No

What IS Available (Standard Library)

✅ AVAILABLE - Standard library only

import json # ✅ JSON parsing import datetime # ✅ Date/time operations import re # ✅ Regular expressions import base64 # ✅ Base64 encoding/decoding import hashlib # ✅ Hashing functions import urllib.parse # ✅ URL parsing import math # ✅ Math functions import random # ✅ Random numbers import statistics # ✅ Statistical functions

Workarounds

Need HTTP requests?

✅ Use HTTP Request node before Code node ✅ Or switch to JavaScript and use $helpers.httpRequest()

Need data analysis (pandas/numpy)?

✅ Use Python statistics module for basic stats ✅ Or switch to JavaScript for most operations ✅ Manual calculations with lists and dictionaries

Need web scraping (BeautifulSoup)?

✅ Use HTTP Request node + HTML Extract node ✅ Or switch to JavaScript with regex/string methods

See: STANDARD_LIBRARY.md for complete reference

Common Patterns Overview

Based on production workflows, here are the most useful Python patterns:

  1. Data Transformation

Transform all items with list comprehensions

items = _input.all()

return [ { "json": { "id": item["json"].get("id"), "name": item["json"].get("name", "Unknown").upper(), "processed": True } } for item in items ]

  1. Filtering & Aggregation

Sum, filter, count with built-in functions

items = _input.all() total = sum(item["json"].get("amount", 0) for item in items) valid_items = [item for item in items if item["json"].get("amount", 0) > 0]

return [{ "json": { "total": total, "count": len(valid_items) } }]

  1. String Processing with Regex

Extract patterns from text

import re

items = input.all() email_pattern = r'\b[A-Za-z0-9.%+-]+@[A-Za-z0-9.-]+.[A-Z|a-z]{2,}\b'

all_emails = [] for item in items: text = item["json"].get("text", "") emails = re.findall(email_pattern, text) all_emails.extend(emails)

Remove duplicates

unique_emails = list(set(all_emails))

return [{ "json": { "emails": unique_emails, "count": len(unique_emails) } }]

  1. Data Validation

Validate and clean data

items = _input.all() validated = []

for item in items: data = item["json"] errors = []

# Validate fields
if not data.get("email"):
    errors.append("Email required")
if not data.get("name"):
    errors.append("Name required")

validated.append({
    "json": {
        **data,
        "valid": len(errors) == 0,
        "errors": errors if errors else None
    }
})

return validated

  1. Statistical Analysis

Calculate statistics with statistics module

from statistics import mean, median, stdev

items = _input.all() values = [item["json"].get("value", 0) for item in items if "value" in item["json"]]

if values: return [{ "json": { "mean": mean(values), "median": median(values), "stdev": stdev(values) if len(values) > 1 else 0, "min": min(values), "max": max(values), "count": len(values) } }] else: return [{"json": {"error": "No values found"}}]

See: COMMON_PATTERNS.md for 10 detailed Python patterns

Error Prevention - Top 5 Mistakes

1: Importing External Libraries (Python-Specific!)

❌ WRONG: Trying to import external library

import requests # ModuleNotFoundError!

✅ CORRECT: Use HTTP Request node or JavaScript

Add HTTP Request node before Code node

OR switch to JavaScript and use $helpers.httpRequest()

2: Empty Code or Missing Return

❌ WRONG: No return statement

items = _input.all()

Processing...

Forgot to return!

✅ CORRECT: Always return data

items = _input.all()

Processing...

return [{"json": item["json"]} for item in items]

3: Incorrect Return Format

❌ WRONG: Returning dict instead of list

return {"json": {"result": "success"}}

✅ CORRECT: List wrapper required

return [{"json": {"result": "success"}}]

4: KeyError on Dictionary Access

❌ WRONG: Direct access crashes if missing

name = _json["user"]["name"] # KeyError!

✅ CORRECT: Use .get() for safe access

name = _json.get("user", {}).get("name", "Unknown")

5: Webhook Body Nesting

❌ WRONG: Direct access to webhook data

email = _json["email"] # KeyError!

✅ CORRECT: Webhook data under ["body"]

email = _json["body"]["email"]

✅ BETTER: Safe access with .get()

email = _json.get("body", {}).get("email", "no-email")

See: ERROR_PATTERNS.md for comprehensive error guide

Standard Library Reference Most Useful Modules

JSON operations

import json data = json.loads(json_string) json_output = json.dumps({"key": "value"})

Date/time

from datetime import datetime, timedelta now = datetime.now() tomorrow = now + timedelta(days=1) formatted = now.strftime("%Y-%m-%d")

Regular expressions

import re matches = re.findall(r'\d+', text) cleaned = re.sub(r'[^\w\s]', '', text)

Base64 encoding

import base64 encoded = base64.b64encode(data).decode() decoded = base64.b64decode(encoded)

Hashing

import hashlib hash_value = hashlib.sha256(text.encode()).hexdigest()

URL parsing

import urllib.parse params = urllib.parse.urlencode({"key": "value"}) parsed = urllib.parse.urlparse(url)

Statistics

from statistics import mean, median, stdev average = mean([1, 2, 3, 4, 5])

See: STANDARD_LIBRARY.md for complete reference

Best Practices 1. Always Use .get() for Dictionary Access

✅ SAFE: Won't crash if field missing

value = item["json"].get("field", "default")

❌ RISKY: Crashes if field doesn't exist

value = item["json"]["field"]

  1. Handle None/Null Values Explicitly

✅ GOOD: Default to 0 if None

amount = item["json"].get("amount") or 0

✅ GOOD: Check for None explicitly

text = item["json"].get("text") if text is None: text = ""

  1. Use List Comprehensions for Filtering

✅ PYTHONIC: List comprehension

valid = [item for item in items if item["json"].get("active")]

❌ VERBOSE: Manual loop

valid = [] for item in items: if item["json"].get("active"): valid.append(item)

  1. Return Consistent Structure

✅ CONSISTENT: Always list with "json" key

return [{"json": result}] # Single result return results # Multiple results (already formatted) return [] # No results

  1. Debug with print() Statements

Debug statements appear in browser console (F12)

items = _input.all() print(f"Processing {len(items)} items") print(f"First item: {items[0] if items else 'None'}")

When to Use Python vs JavaScript Use Python When: ✅ You need statistics module for statistical operations ✅ You're significantly more comfortable with Python syntax ✅ Your logic maps well to list comprehensions ✅ You need specific standard library functions Use JavaScript When: ✅ You need HTTP requests ($helpers.httpRequest()) ✅ You need advanced date/time (DateTime/Luxon) ✅ You want better n8n integration ✅ For 95% of use cases (recommended) Consider Other Nodes When: ❌ Simple field mapping → Use Set node ❌ Basic filtering → Use Filter node ❌ Simple conditionals → Use IF or Switch node ❌ HTTP requests only → Use HTTP Request node Integration with Other Skills Works With:

n8n Expression Syntax:

Expressions use {{ }} syntax in other nodes Code nodes use Python directly (no {{ }}) When to use expressions vs code

n8n MCP Tools Expert:

How to find Code node: search_nodes({query: "code"}) Get configuration help: get_node_essentials("nodes-base.code") Validate code: validate_node_operation()

n8n Node Configuration:

Mode selection (All Items vs Each Item) Language selection (Python vs JavaScript) Understanding property dependencies

n8n Workflow Patterns:

Code nodes in transformation step When to use Python vs JavaScript in patterns

n8n Validation Expert:

Validate Code node configuration Handle validation errors Auto-fix common issues

n8n Code JavaScript:

When to use JavaScript instead Comparison of JavaScript vs Python features Migration from Python to JavaScript Quick Reference Checklist

Before deploying Python Code nodes, verify:

Considered JavaScript first - Using Python only when necessary Code is not empty - Must have meaningful logic Return statement exists - Must return list of dictionaries Proper return format - Each item: {"json": {...}} Data access correct - Using _input.all(), _input.first(), or _input.item No external imports - Only standard library (json, datetime, re, etc.) Safe dictionary access - Using .get() to avoid KeyError Webhook data - Access via ["body"] if from webhook Mode selection - "All Items" for most cases Output consistent - All code paths return same structure Additional Resources Related Files DATA_ACCESS.md - Comprehensive Python data access patterns COMMON_PATTERNS.md - 10 Python patterns for n8n ERROR_PATTERNS.md - Top 5 errors and solutions STANDARD_LIBRARY.md - Complete standard library reference n8n Documentation Code Node Guide: https://docs.n8n.io/code/code-node/ Python in n8n: https://docs.n8n.io/code/builtin/python-modules/

Ready to write Python in n8n Code nodes - but consider JavaScript first! Use Python for specific needs, reference the error patterns guide to avoid common mistakes, and leverage the standard library effectively.

返回排行榜