Обучение и инструменты 09.01.2026 477 просмотров

Python в n8n: пишем кастомный код в Code Node с нуля

#Python #n8n #Code Node #скрипты #автоматизация #разработка
Статья на тему: Python в n8n: пишем кастомный код в Code Node с нуля

Введение

n8n славится своим low-code подходом: сотни готовых узлов (nodes) позволяют строить сложные интеграции, не написав ни строчки кода. Но что делать, если вам нужно распарсить сложный XML-файл, обучить простую модель машинного обучения "на лету" или использовать специфическую криптографическую библиотеку для подписи банковских запросов?

Для таких задач в n8n есть универсальный узел Code. И если раньше в нем правил только JavaScript, то недавно разработчики добавили нативную поддержку Python — языка номер один для работы с данными и ИИ. В этой статье мы с нуля разберем, как писать, тестировать и использовать Python-код прямо внутри ваших сценариев n8n.

Как устроен Code Node для Python?

Если вы добавите узел Code на холст n8n и переключите язык на Python (Pyodide), вы увидите редактор кода. Под капотом n8n не запускает полноценный процесс Python на сервере (что было бы медленно и небезопасно). Вместо этого используется Pyodide — среда выполнения Python, скомпилированная в WebAssembly. Это означает, что ваш Python-код выполняется очень быстро и безопасно прямо в той же среде (Node.js или браузере), где работает сам n8n.

Основы: Ввод и вывод данных

Главное правило узла Code: он должен принять данные от предыдущего узла, как-то их изменить и передать следующему. В n8n данные между узлами всегда передаются в виде массива объектов (items).

Чтение данных (Input)

Чтобы получить доступ к данным, которые пришли в узел, используется специальная переменная _input. Чаще всего вам понадобится метод _input.all(), который возвращает весь список элементов.

# Получаем все входящие элементы
items = _input.all()

# Берем первый элемент и обращаемся к его JSON-телу
first_item = items[0]
user_name = first_item.json["name"]

Возврат данных (Output)

Чтобы передать данные дальше по цепочке, скрипт должен завершиться возвратом списка объектов (массива словарей в терминах Python). Обязательно сформируйте на выходе валидную для n8n структуру.

return [
    {
        "json": {
            "greeting": f"Привет, {user_name}!"
        }
    }
]

Практический пример: Очистка телефонных номеров

Представим задачу: из CRM приходят кривые номера телефонов: "+7 (999) 123-45-67", "89991234567", "999-123-45-67". Нам нужно привести их к единому стандарту "79991234567" перед отправкой в SMS-шлюз.

Вставляем этот код в узел Code на Python:

import re

items = _input.all()
cleaned_items = []

for item in items:
    # Берем телефон из входящего JSON
    raw_phone = item.json.get("phone", "")
    
    # Регулярным выражением оставляем только цифры
    digits_only = re.sub(r'\D', '', raw_phone)
    
    # Приводим к стандарту РФ
    if len(digits_only) == 10:
        clean_phone = "7" + digits_only
    elif len(digits_only) == 11 and digits_only.startswith("8"):
        clean_phone = "7" + digits_only[1:]
    else:
        clean_phone = digits_only # Оставляем как есть, если формат другой
        
    # Создаем новый объект для отправки дальше
    new_item = {
        "json": {
            "original_phone": raw_phone,
            "clean_phone": clean_phone
        }
    }
    cleaned_items.append(new_item)

return cleaned_items

Как использовать внешние библиотеки (Pandas, Numpy)?

Самое вкусное в Python — это библиотеки. Так как n8n использует Pyodide, вы можете импортировать многие популярные пакеты для работы с данными, просто прописав import!

Например, если вам нужно сгруппировать большой массив данных о продажах и посчитать средний чек, использование pandas будет гораздо быстрее, чем собирать сложную логику на узлах n8n.

import pandas as pd

# Конвертируем JSON от n8n в красивый DataFrame Pandas
items = _input.all()
data = [item.json for item in items]
df = pd.DataFrame(data)

# Группируем по менеджеру и считаем среднюю сумму продажи
summary = df.groupby('manager')['amount'].mean().reset_index()

# Конвертируем DataFrame обратно в список словарей для n8n
result_json = summary.to_dict(orient='records')

final_items = []
for row in result_json:
    final_items.append({"json": row})

return final_items

Важно: В Pyodide доступны пакеты, скомпилированные под WebAssembly (numpy, pandas, scipy). Библиотеки, требующие компиляции C-кода (например, некоторые базы данных или сложные ML-модели), работать не будут.

Ограничения и советы по оптимизации

  1. Холодный старт: При первом исполнении узла Python-окружение Pyodide должно инициализироваться в оперативной памяти (это может занять 1-2 секунды). Последующие запуски будут молниеносными.
  2. Синхронность: Код в узле Python выполняется синхронно. Если вы напишете скрипт, считающий факториал миллиона, он заблокирует выполнение всего workflow, пока не закончит работу.
  3. API запросы: Несмотря на то что в Python есть библиотека requests, в экосистеме n8n для отправки HTTP-запросов настоятельно рекомендуется использовать стандартный узел HTTP Request, а узел Code оставить исключительно для обработки и трансформации (трансмутации) данных.

Заключение

Добавление Python в n8n сняло последние ограничения платформы. Теперь аналитики данных, инженеры по машинному обучению и backend-разработчики могут переносить свои любимые скрипты на pandas и numpy прямо в визуальные workflow, наслаждаясь скоростью работы и мощью огромной экосистемы Python.

Полезные материалы по теме