Execute Python
The do-anything node that only runs code you wrote yourself
- arg0
- res0
The honest name
This whole pack is a single node: Execute Python. The name is not marketing. You type Python into a box, it runs, and whatever you assign to result comes out the other side as an output. No API calls, no API keys, no hidden steps.
You reach for it the way you reach for a Swiss Army knife - when the answer is two lines of code and no node pack ships those two lines. Need to rework a filename, do arithmetic on a seed, massage a string before it hits the prompt, or crunch numbers on a tensor? Instead of hunting through WAS and Efficiency nodes for the right gizmo, you just write it. The author built it because "2-3 lines of Python would do the job" and nothing else accepted arbitrary inputs or returned arbitrary types. Its closest cousin is rgthree's Power Puter, which is the safe version: it evaluates a controlled list of functions. This node is the opposite of that - it runs any Python, imports included. That trade-off is the whole story of this pack.
How it actually runs your code
Two widgets matter: code (a big multiline box, with a proper code editor that gets syntax highlighting from Ace) and n_outputs (an integer, 1–10, that decides how many outputs the node shows). There's one declared input, arg0, typed * (any type) - and here's the neat part: wire a second connection onto the node and it grows an arg1 input on the fly, then arg2, and so on, all of them *. The frontend reconciles inputs and outputs as you connect things.
Under the hood it's just Python's exec. Each wired argN becomes a variable of that name inside your code, so you can pass in an image, a string, even a model. Then you assign result. For a single output, a bare value works; for multiple, result must be a tuple that matches n_outputs exactly, like result = 1, 2, 3 with n_outputs = 3 (a list also gets converted). The output, res0 (type *), feeds anything downstream - because * accepts any type, you can hand your result to almost any node.
The weird part: your machine's fingerprint
Notice the node's class name ends in a long hex string - ExecutePython93afc7b4dfdd1411.... That suffix is a hash of your machine ID, generated by the pack's one dependency, py-machineid. It means the node only runs on the machine that created the workflow. Download someone else's workflow containing it and it simply won't load for you (the hash in this page's URL is from the machine that indexed it - yours will differ). The author added this deliberately after the community pushed on security: a shared workflow can't sneak its code onto your box. Trade-off: this node is for your workflows, not for ones you share. If someone hands you one, the repo ships a claim_workflow.py script that re-stamps the node IDs in the workflow JSON to your machine - but you'd be insane to run that before reading the code.
Install
Two easy routes:
# ComfyUI Manager: search for "Execute Python"
# or:
cd ComfyUI/custom_nodes
git clone https://github.com/mozhaa/ComfyUI-Execute-Python
Restart ComfyUI. The only Python dependency is py-machineid - a tiny package, no model files, nothing heavy. One caveat: the code editor pulls Ace from a CDN, so if you run offline, syntax highlighting quietly disappears and you get a plain text box (the node still works).
Security - read this before you wire anything
This is exec on arbitrary text, running with your full user privileges. There is no sandbox. The README's warning is blunt: "execute only trusted Python code." The wider ecosystem knows this node class well - near-identical scripting nodes have been planted on internet-exposed ComfyUI instances to run crypto-stealing code, and this one openly violates Comfy's registry standard against eval/exec, so it'll never be registry-blessed. Your rules: only run code you wrote, and if you ever load a downloaded workflow, audit every subgraph for this node before hitting Queue. That's not paranoia - the whole point of the machine lock is that you're the only person who should ever run your code.
Common issues
- "
resultvariable was not assigned" - you forgot to setresult. Add it somewhere in your code. - "expected tuple of length N" -
n_outputssays 3 but you returned 2 values. Count your outputs, or fix the tuple. - Node missing when loading a shared workflow - that's the machine lock doing its job, not a broken install.
- Highlighting gone - you're offline; Ace couldn't load from the CDN.
Since outputs are *, wire your result into a text-display or preview node to see what came out before it touches anything important.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| code | STRING | — | |
| n_outputs | INT | 11–10 | — |
| arg0opt | * | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| res0 | * | — |