Python natif dans n8n : installer pandas et numpy avec le Task Runner
Par Clément Lacaille (Tech-Bharat) · Publié le 21 septembre 2026 · 5 min de lecture · notre méthode
Pack Assistant RAG — 119 €
4 workflows n8n prêts à importer, guide en français, garantie 14 jours
Le Python (Beta) du node Code tourne sur Pyodide, une distribution de CPython compilée en WebAssembly : pratique parce qu’elle ne demande aucune installation, mais fermée à pandas, numpy ou tout package tiers non pré-embarqué. Depuis n8n 1.111, une seconde voie existe pour les instances self-hosted : un runner Python natif, qui exécute un vrai interpréteur CPython dans son propre processus, avec un accès réel à pip et à PyPI. Ce guide explique comment l’activer, comment y installer des bibliothèques de data science, et où s’arrêtent ses avantages par rapport à Pyodide.
Deux Python, pas un seul
Il est facile de confondre les deux options tant elles partagent le même sélecteur dans le node Code. La différence est pourtant fondamentale :
| Python (Beta) — Pyodide | Python natif — Task Runner | |
|---|---|---|
| Moteur | CPython compilé en WebAssembly | CPython natif, processus séparé |
| Packages tiers | Liste fermée précompilée pour Pyodide | N’importe quel package PyPI, si installé et autorisé |
| Disponible sur n8n Cloud | Oui | Non |
| Configuration requise | Aucune | Image Docker personnalisée + variables d’environnement |
| Isolation | Sandbox WebAssembly, dans le processus n8n | Processus Task Runner dédié, idéalement en mode externe |
Le runner natif ne remplace donc pas Pyodide : il ouvre une option supplémentaire pour le self-hosted, au prix d’un peu de configuration côté infrastructure. Si votre code ne dépend d’aucun package externe, Pyodide reste le choix le plus simple — il fonctionne à l’identique en cloud et en self-hosted, sans image Docker à maintenir.
Activer le runner natif
Sur l’instance n8n principale, une seule variable suffit à basculer le Code node en mode natif pour les exécutions Python :
N8N_NATIVE_PYTHON_RUNNER=true
Cette variable s’applique à l’instance n8n elle-même (pas au conteneur runner). Basculer un environnement qui a déjà des scripts Python en production dessus est un changement de comportement, pas un ajout neutre : le nouvel exécuteur ne reproduit pas forcément à l’identique les particularités de Pyodide. Activez-le d’abord sur un environnement de staging, exécutez vos workflows Python existants, et ne basculez qu’un seul environnement à la fois.
Installer pandas, numpy et le reste avec uv
L’image officielle n8nio/runners embarque uv, un remplaçant de pip nettement plus rapide, déjà présent dans l’environnement du runner Python. Pour ajouter des packages, on construit une image qui étend l’image officielle plutôt que d’installer à la volée dans un conteneur éphémère :
FROM n8nio/runners:1.121.0
USER root
RUN cd /opt/runners/task-runner-python && uv pip install pandas numpy
Deux points à respecter :
- Le tag de l’image
n8nio/runnersdoit correspondre à la version den8nio/n8nutilisée par votre instance. Un décalage de version entre l’instance principale et le runner est une source classique d’erreurs difficiles à diagnostiquer. - Installer dans une image versionnée, pas dans un conteneur en cours d’exécution. Un
docker execponctuel pour ajouter un package ne survit pas à un redéploiement sans volume dédié ; l’image personnalisée, elle, reproduit l’environnement à l’identique à chaque déploiement — le même principe que celui déjà recommandé pour ajouter des modules npm au node Code JavaScript.
L’allowlist obligatoire : N8N_RUNNERS_EXTERNAL_ALLOW
Installer un package dans l’image ne suffit pas à le rendre importable : il faut aussi l’autoriser explicitement, package par package, via une variable placée sur le conteneur runner :
N8N_RUNNERS_EXTERNAL_ALLOW=pandas,numpy
Cette liste blanche séparée par des virgules n’est pas une contrainte gratuite. Elle répond à un problème documenté du côté de l’écosystème PyPI lui-même : une étude de Neupane, Holmes, Wyss, Davidson et De Carli publiée au USENIX Security Symposium 2023 recense plus de 1 200 attaques réelles de « confusion de paquets » (typosquatting, mais aussi des mécanismes bien plus subtils que la simple faute de frappe) qui ont conduit des développeurs à installer, sans le vouloir, un package malveillant à la place du bon. Sur une instance n8n qui exécute des workflows métier et manipule des credentials, forcer une allowlist explicite plutôt qu’un import libre limite mécaniquement la surface d’attaque : même un package installé par erreur ou compromis après coup reste inutilisable tant qu’il n’a pas été ajouté à la liste, à la main, par la personne qui administre l’instance.
Un cas d’usage concret : nettoyer des données avant de les indexer
Le runner natif prend tout son sens sur des étapes de préparation de données trop lourdes pour l’IF/Set habituels de n8n. Exemple typique : avant d’alimenter un pipeline RAG comme celui du Pack Assistant RAG, un node Code Python natif peut dédupliquer des lignes proches avec pandas, normaliser des colonnes numériques avec numpy, ou filtrer un export CSV volumineux avant de le transmettre au workflow d’ingestion PDF vers Supabase pgvector. Ce type de traitement tabulaire, pénible à écrire en JavaScript pur, devient une poignée de lignes idiomatiques une fois pandas réellement disponible — ce qui n’était pas le cas avec Pyodide.
Ce qui ne change pas sur n8n Cloud
Rien de tout cela ne s’applique à n8n Cloud. L’option Python du node Code y reste volontairement fermée : ni bibliothèque standard étendue, ni package tiers, pour une raison simple — Cloud ne permet pas de construire une image Docker personnalisée pour le runner. Si votre besoin de traitement de données dépasse ce que permet Pyodide et que vous êtes sur Cloud, la seule voie reste un microservice externe appelé en HTTP Request, comme évoqué dans le guide sur Python et Pyodide. Le runner natif est, par construction, un avantage du self-hosted.
En résumé
Le runner Python natif ne rend pas Pyodide obsolète : il ajoute une option pour les cas où une vraie bibliothèque PyPI est nécessaire, réservée aux instances self-hosted prêtes à maintenir une image Docker dédiée. La checklist tient en quatre points : N8N_NATIVE_PYTHON_RUNNER=true sur l’instance, une image qui étend n8nio/runners avec uv pip install, une version d’image alignée sur celle de n8n, et un N8N_RUNNERS_EXTERNAL_ALLOW qui ne liste que ce qui est réellement nécessaire. Le reste — Pyodide, ou un microservice externe — continue de couvrir tous les autres cas, y compris sur Cloud.
FAQ
Questions fréquentes
Le Python natif remplace-t-il le Python (Beta) du node Code ?
Non, les deux coexistent. Le Python (Beta) historique tourne toujours sur Pyodide, y compris sur n8n Cloud. Le runner natif est une option supplémentaire, à activer explicitement en self-hosted, qui exécute un vrai CPython dans un Task Runner séparé. Basculer dessus est un changement de comportement : testez vos scripts existants avant de l’activer sur une instance de production.
Peut-on utiliser pandas et numpy sur n8n Cloud ?
Non. Sur n8n Cloud, l’option Python du node Code n’autorise l’import d’aucune bibliothèque, ni de la bibliothèque standard ni d’un package tiers. Le runner Python natif avec accès à pip suppose de construire sa propre image Docker : c’est une fonctionnalité self-hosted par construction.
Que se passe-t-il si un package est installé mais absent de l’allowlist ?
L’import échoue à l’exécution, même si le package est bien présent dans l’environnement du runner. N8N_RUNNERS_EXTERNAL_ALLOW fonctionne comme une liste blanche stricte : installer un package avec uv pip ne suffit pas, il faut aussi l’ajouter explicitement à cette variable pour que le Task Runner accepte de l’importer.
Faut-il migrer tous ses scripts Python vers le runner natif ?
Non. Pour du simple parsing ou des transformations sans dépendance externe, le Python (Beta) sur Pyodide reste plus simple : rien à construire, ça fonctionne aussi bien en cloud qu’en self-hosted. Le runner natif se justifie quand un workflow a réellement besoin d’une bibliothèque tierce comme pandas, numpy ou une librairie métier interne.