python-runner-pro-max

n8n community node that runs Python in uv-managed, versioned environments

Package Information

Released: 2 mo ago
Downloads: 0 weekly / 0 monthly
Latest Version: 0.1.0

Documentation

n8n Python Runner Pro Max

A self-hosted n8n community node plus an isolated executor service. Each execution selects a Python version and a package requirement list. The executor uses uv to create an immutable cached virtual environment keyed by:

  • requested Python version
  • normalized package list

Changing packages creates or reuses a different environment. No n8n or executor container restart is required.

Security warning

This node runs arbitrary Python and installs third-party packages. Treat access to it as administrator-level remote code execution. Keep the executor on an internal Docker network, use a long random token, pin/constrain packages, and restrict who can edit or execute workflows containing this node. The included container limits are a baseline, not a complete hostile-code sandbox.

Build the node

npm install
npm run build
npm pack

This creates a package such as n8n-nodes-python-runner-pro-max-0.1.0.tgz. Publish it to a private/public npm registry, or install it manually in the n8n custom extensions directory according to your n8n deployment method.

Start the executor

Copy docker-compose.override.yml beside your existing Compose file and add this to .env:

UV_PYTHON_EXECUTOR_TOKEN=replace-with-output-of-openssl-rand-hex-32

Generate it with:

openssl rand -hex 32

Because the override uses ./executor, either keep this repository beside the Compose file or change the build context to the repository's executor directory.

Start it:

docker compose -f n8n-docker-compose.yaml -f docker-compose.override.yml up -d --build uv-python-executor n8n

Configure the n8n credential

Create UV Python Executor API credentials:

  • Base URL: http://uv-python-executor:8080
  • API Token: the same UV_PYTHON_EXECUTOR_TOKEN

Node contract

Input JSON items are available in Python as items. Assign JSON-serializable output to result.

import requests

response = requests.get("https://example.com", timeout=20)
result = [{
    "status": response.status_code,
    "inputCount": len(items),
}]

Packages field:

requests==2.32.3
pandas>=2.2,<3

The service rejects URLs, Git/VCS dependencies, local paths, pip options, editable installs, and—by default—unversioned packages.

How on-the-fly updates work

The environment ID is a hash of the Python request and requirements. For example:

Python 3.12 + requests==2.32.3  -> environment A
Python 3.12 + requests==2.32.4  -> environment B
Python 3.13 + requests==2.32.4  -> environment C

Creation is locked and staged, then atomically renamed into place. Existing executions continue using their existing environment.

Important limitations

  • First execution for a new environment may take time while uv downloads Python and wheels.
  • Native packages still depend on compatible manylinux wheels or OS libraries.
  • Cached environments consume disk and need an external cleanup policy.
  • The example returns JSON only; binary output needs an additional upload/download protocol.
  • Python subprocess isolation is not equivalent to a hardened multi-tenant sandbox. For untrusted users, run each execution as a short-lived container/VM with network and filesystem policy.

Discussion