FlowKit

Python dans le node Code de n8n : possibilités, limites et alternatives

Publié le 27 juillet 2026 · 8 min de lecture

Le node Code de n8n est surtout connu pour son JavaScript, mais un sélecteur discret en haut du panneau propose une seconde option : Python (Beta). Pour les équipes data ou les développeurs qui pensent en list comprehensions plutôt qu'en .map(), la tentation est forte d'écrire toute la logique de transformation en Python. C'est possible — mais dans un cadre plus contraint qu'il n'y paraît, car ce Python ne tourne pas comme un script classique sur le serveur. Ce guide fait le tour de ce qui marche vraiment, des limites concrètes de l'implémentation, et des alternatives sérieuses quand Python est réellement indispensable.

Comment n8n exécute du Python : Pyodide, pas un interpréteur système

Quand vous sélectionnez Python dans le node Code, n8n n'appelle pas un binaire python3 installé sur la machine. Il exécute votre code via Pyodide, une distribution de CPython compilée en WebAssembly, qui tourne à l'intérieur même du processus n8n. Cette architecture a deux conséquences majeures :

  • Aucune dépendance à installer côté serveur. Le Python fonctionne à l'identique sur n8n Cloud et en self-hosted, sans que l'administrateur ait quoi que ce soit à configurer.
  • Un environnement sandboxé. Le code n'a pas d'accès direct au réseau, au système de fichiers du serveur, ni aux packages installés via pip sur la machine. Vous êtes dans une bulle WebAssembly, pas dans un shell.

C'est un vrai CPython — la syntaxe, la bibliothèque standard (json, re, datetime, collections, hashlib…) et la sémantique du langage sont bien là. Mais ce n'est pas l'environnement Python complet auquel un data engineer est habitué.

La syntaxe d'accès aux données : underscore au lieu de dollar

En JavaScript, le node Code expose $input, $json, $('Nom du Node'). En Python, le caractère $ n'est pas valide dans un identifiant : n8n remplace donc le préfixe par un underscore. La correspondance est directe :

JavaScript Python
$input.all() _input.all()
$json _json
$('Get Customer') _('Get Customer')
$input.first() _input.first()

Le format des items, lui, ne change pas : le node reçoit et doit retourner une liste de dictionnaires avec une clé json (et éventuellement binary). Oublier cette enveloppe reste l'erreur n° 1, en Python comme en JavaScript :

# Run Once for All Items — structure minimale
items = _input.all()

results = []
for item in items:
    results.append({
        "json": {
            "email": item.json.get("email", "").strip().lower()
        }
    })

return results

Les deux modes d'exécution — Run Once for All Items et Run Once for Each Item — fonctionnent comme en JavaScript : le premier voit tous les items d'un coup via _input.all(), le second s'exécute item par item avec _json représentant l'item courant.

Trois exemples concrets

Transformer des items avec une list comprehension

Le pattern map/filter s'écrit de façon très naturelle en Python :

items = _input.all()

# Ne garder que les commandes > 100 € et calculer un prix remisé
return [
    {
        "json": {
            **item.json,
            "price_discounted": round(item.json["total"] * 0.9, 2)
        }
    }
    for item in items
    if item.json.get("total", 0) > 100
]

C'est l'équivalent direct du duo .filter().map() en JavaScript — question de goût et d'habitude d'équipe, pas de capacité.

Dédoublonner sur une clé

Un classique après avoir combiné plusieurs sources avec un node Merge : éliminer les doublons sur l'email en gardant la première occurrence.

items = _input.all()
seen = set()
unique = []

for item in items:
    key = item.json.get("email", "").strip().lower()
    if key and key not in seen:
        seen.add(key)
        unique.append({"json": item.json})

return unique

Parser des dates hétérogènes

Le module datetime de la stdlib est disponible, ce qui rend le nettoyage de dates plus agréable qu'en JavaScript vanilla :

from datetime import datetime

FORMATS = ["%d/%m/%Y", "%Y-%m-%d", "%d %b %Y"]

def parse_date(raw):
    for fmt in FORMATS:
        try:
            return datetime.strptime(raw.strip(), fmt).date().isoformat()
        except (ValueError, AttributeError):
            continue
    return None

return [
    {"json": {**item.json, "date_normalized": parse_date(item.json.get("date"))}}
    for item in _input.all()
]

Ce genre de normalisation est typiquement ce qu'on place avant un node d'export Excel ou CSV, pour que toutes les lignes partagent le même format de date.

Les limites réelles à connaître avant de tout écrire en Python

Pas d'accès réseau ni fichier. Pas de requests, pas d'open() sur un fichier du serveur, pas de socket. Tout appel externe doit passer par un node dédié — HTTP Request avec sa gestion de pagination, nodes d'intégration, etc. Le node Code Python sert à transformer des données, pas à en chercher.

Uniquement la stdlib et les packages compatibles Pyodide. La bibliothèque standard est là, ainsi que les packages purs Python (ou précompilés pour WebAssembly) que Pyodide sait charger. Mais la liste effectivement disponible dans le node Code dépend de la version de Pyodide embarquée par votre version de n8n : ne bâtissez pas un workflow critique sur l'hypothèse que pandas ou numpy seront importables — testez l'import dans votre instance avant de vous engager, et prévoyez un plan B.

Un démarrage plus lent que JavaScript. Le runtime Pyodide doit s'initialiser, là où le JavaScript s'exécute nativement dans Node.js. Sur une exécution ponctuelle, c'est imperceptible ; sur un workflow déclenché des centaines de fois par heure ou une boucle qui traite de gros lots, le surcoût se cumule et se voit dans les temps d'exécution.

Un statut Beta. n8n l'affiche explicitement : la variante Python du node Code est en Beta, et certaines fonctions utilitaires disponibles côté JavaScript n'ont pas d'équivalent Python. En cas de comportement étrange, le premier réflexe de débogage est de reproduire la logique en JavaScript pour isoler si le problème vient du code ou du runtime.

Quand préférer JavaScript (spoiler : par défaut)

n8n recommande JavaScript comme langage par défaut du node Code, et c'est un conseil à suivre : exécution native, démarrage immédiat, meilleure couverture des fonctions intégrées, et la quasi-totalité des exemples de la communauté sont écrits en JS.

Faut-il pour autant forcer une équipe Python à écrire du JavaScript ? Pas nécessairement. Une étude classique de Lutz Prechelt, An Empirical Comparison of Seven Programming Languages (IEEE Computer, 2000 — voir sur Google Scholar), a comparé les mêmes programmes écrits en sept langages et abouti à un résultat devenu célèbre : la variance de productivité et de qualité entre développeurs dépasse largement celle entre langages. Autrement dit, le facteur dominant n'est pas le langage, mais la maîtrise qu'en a la personne qui l'écrit. Pour un node Code qui fait de la pure transformation de données, choisissez le langage que votre équipe relit et débogue le plus vite — les deux variantes font le travail.

La vraie ligne de partage n'est donc pas « JS ou Python », mais « node Code ou pas node Code » : dès que la logique exige des bibliothèques absentes de Pyodide, du réseau ou du fichier, aucune des deux variantes ne suffit.

Quand Python est indispensable : les deux alternatives sérieuses

Un microservice FastAPI ou Flask appelé via HTTP Request

L'architecture la plus propre : votre code Python tourne dans son propre service (avec pandas, scikit-learn, pdfplumber — ce que vous voulez), exposé en HTTP, et n8n l'appelle comme n'importe quelle API.

# microservice FastAPI minimal
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Payload(BaseModel):
    items: list[dict]

@app.post("/transform")
def transform(payload: Payload):
    # ici : pandas, ML, tout l'écosystème Python
    return {"items": [enrich(i) for i in payload.items]}

Côté n8n, un node HTTP Request envoie les items en POST et récupère le résultat. Pensez à configurer timeout et retry sur cet appel, et à protéger l'endpoint par un token stocké dans un credential n8n plutôt qu'en dur. C'est l'approche qu'on retrouve dans les pipelines documentaires avancés : le Pack Assistant RAG (119 €) suit exactement ce principe de séparation — n8n orchestre, et les traitements lourds (embeddings, extraction) sont délégués à des services spécialisés appelés en HTTP.

Le node Execute Command sur une instance self-hosted

Sur un self-hosted où Python est installé, le node Execute Command peut lancer un script directement sur la machine : python3 /scripts/transform.py. C'est simple et sans service supplémentaire, mais avec des précautions non négociables :

  • le node est indisponible sur n8n Cloud, et exécute des commandes avec les droits du processus n8n — n'y injectez jamais une valeur venant d'un webhook sans validation stricte (risque d'injection de commande) ;
  • les dépendances Python doivent être installées et versionnées sur l'hôte (ou dans l'image Docker), ce qui recrée la gestion d'environnement que le node Code évitait ;
  • encadrez l'appel d'un Error Workflow : un script qui sort en code d'erreur ne doit pas échouer en silence.

Tableau de décision : JS, Python-Pyodide ou microservice

Critère JavaScript (node Code) Python-Pyodide (node Code) Microservice Python
Transformation de données simple ✅ Recommandé par défaut ✅ OK si l'équipe est Python ❌ Surdimensionné
Performances / démarrage Natif, rapide Plus lent (init Pyodide) Latence réseau, mais scalable
pandas, numpy, ML ⚠️ Non garanti, à tester ✅ Écosystème complet
Accès réseau / fichiers ❌ (par design) ❌ (par design)
Fonctionne sur n8n Cloud ✅ (service hébergé à part)
Maintenance Aucune Aucune Un service à déployer et superviser
Maturité dans n8n Stable Beta Dépend de vous

En résumé

Le Python du node Code est un vrai Python, parfait pour la transformation d'items quand votre équipe y est plus à l'aise qu'en JavaScript : la syntaxe _input.all() / _json reprend celle du JS avec un underscore à la place du dollar, et la stdlib couvre le parsing, le dédoublonnage et la normalisation sans effort. Mais Pyodide impose ses règles — pas de réseau, pas de fichier, pas de garantie sur les packages scientifiques, un démarrage plus lent — et le statut Beta invite à garder JavaScript comme défaut pour tout ce qui est trivial. Le jour où votre logique réclame le vrai écosystème Python, ne tordez pas le node Code : un microservice FastAPI appelé en HTTP Request, ou un Execute Command bien encadré en self-hosted, feront le travail proprement et durablement.

FAQ

Questions fréquentes

Peut-on vraiment utiliser Python dans n8n ?

Oui. Le node Code propose une option Python (Beta) qui exécute du CPython compilé en WebAssembly via Pyodide, directement dans le processus n8n. La syntaxe d'accès aux données utilise un underscore au lieu du dollar : _input.all() remplace $input.all(). C'est un vrai Python, mais sandboxé : pas d'accès réseau ni fichier direct, et seuls la bibliothèque standard et les packages purs Python supportés par Pyodide sont disponibles.

Peut-on importer pandas ou numpy dans le node Code Python de n8n ?

Il ne faut pas compter dessus. Pyodide supporte la bibliothèque standard Python et une liste de packages précompilés ou purs Python, mais la disponibilité effective dans le node Code de n8n dépend de la version embarquée. Pour un vrai traitement de données avec pandas, la solution fiable est un microservice Python (FastAPI, Flask) appelé via HTTP Request, ou le node Execute Command sur une instance self-hosted avec Python installé.

Pourquoi le node Code Python est-il plus lent que JavaScript dans n8n ?

Parce que le code passe par Pyodide, une couche CPython compilée en WebAssembly qui doit s'initialiser avant chaque exécution, alors que le JavaScript tourne nativement dans le runtime Node.js de n8n. Sur un workflow déclenché fréquemment ou traitant beaucoup d'items, ce surcoût de démarrage se cumule. C'est l'une des raisons pour lesquelles n8n recommande JavaScript par défaut.

Faut-il choisir JavaScript ou Python pour le node Code ?

JavaScript est le choix par défaut recommandé : exécution native, démarrage plus rapide, accès à toutes les fonctions intégrées de n8n. Python se justifie quand l'équipe le maîtrise nettement mieux et que la logique reste du pur traitement de données (transformation, parsing, calculs). Dès qu'il faut des bibliothèques scientifiques, du réseau ou du fichier, passez à un microservice Python externe ou à Execute Command.

Bundle FlowKit Complet

269 €