Compare commits

...
25 Commits
Author SHA1 Message Date
Peyton DeNiro 32d42bf472 Merge pull request #133 from xiaoxidashen/main
Fix comfyui_to_python_utils import error, Fix conflict between comfy/utils.py and utils,Fix not await for load extra nodes
2025-09-26 18:53:00 -05:00
Peyton DeNiro 281b8408c9 Merge pull request #132 from nuaimat/main
Fix "Save as Script" option not available in ComfyUI v0.3.50
2025-09-26 18:23:32 -05:00
chengxi b215c83b76 fix not await for load extra nodes 2025-09-07 14:33:48 +08:00
chengxi 76bc1c343e Fix conflict between comfy/utils.py and utils 2025-09-07 14:33:27 +08:00
chengxi 42bc6926ae fix not found comfyui_to_python_utils 2025-09-07 14:32:28 +08:00
Mo Nuaimat 351a68831d Fix "Save as Script" option not available in ComfyUI v0.3.50 2025-08-27 21:36:29 -07:00
pydn 1c0585fabe Update version number 2025-07-27 19:09:46 -05:00
Peyton DeNiro 60d55d904b Merge pull request #125 from pydn/licence-update
Licence update
2025-07-27 19:06:38 -05:00
pydn 3a5ef069d9 Update .toml file to have MIT license 2025-07-27 18:56:13 -05:00
Peyton DeNiro 77a493f0eb Merge pull request #113 from ComfyNodePRs/update-publish-yaml
Update Github Action for Publishing to Comfy Registry
2025-07-27 18:32:41 -05:00
snomiao 2f6a649801 chore(publish): update GitHub Actions workflow for node publishing
- Added permissions for issue writing
- Updated action version to v1 for publish-node-action
- Added condition to run job only for 'pydn' repository owner
2025-01-25 07:27:37 +00:00
snomiao 4d0de66b0b chore(licence-update): Update PyProject Toml - License 2025-01-21 01:31:31 +00:00
Peyton DeNiro 0aa2747736 Merge pull request #95 from swilcock0/main
Modification to add menu item in new UI
2025-01-14 10:59:52 -06:00
Sam Wilcock 0351a2eaab Update save-as-script.js
Change icon
2025-01-07 00:23:46 +01:00
Sam Wilcock 4276ddbfb1 Update save-as-script.js 2025-01-07 00:19:50 +01:00
Sam Wilcock 0094c08d1c Update save-as-script.js
Add "Save as Script" item to new "Workflow" menu
2025-01-07 00:04:25 +01:00
Peyton DeNiro 14824e3473 Merge pull request #77 from pydn/kwargs-hotfix
Kwargs hotfix
2024-09-15 19:54:41 -05:00
pydn ea32a8fbbe Remove unneeded print statements. 2024-09-15 19:52:36 -05:00
pydn e7363070f1 Made updates to check for missing required arguments and for cases when unique id is passed through kwargs. 2024-09-15 19:48:43 -05:00
Peyton DeNiro 39c22295bc Merge pull request #52 from haohaocreates/publish
Add Github Action for Publishing to Comfy Registry
2024-09-15 10:25:17 -05:00
Peyton DeNiro 881e48a10c Merge pull request #76 from pydn/registry/pyproject
Registry/pyproject
2024-09-15 10:25:00 -05:00
pydn dc6b71b494 Updated .toml 2024-09-15 10:16:09 -05:00
haohaocreates d938df9f4f Update pyproject.toml desc 2024-05-21 20:36:17 -04:00
haohaocreates 9ea8e993c4 chore(publish): Add Github Action for Publishing to Comfy Registry 2024-05-22 00:35:46 +00:00
haohaocreates cdca60ff04 chore(pyproject): Add pyproject.toml for Custom Node Registry 2024-05-22 00:35:46 +00:00
5 changed files with 108 additions and 47 deletions
+25
View File
@@ -0,0 +1,25 @@
name: Publish to Comfy registry
on:
workflow_dispatch:
push:
branches:
- main
paths:
- "pyproject.toml"
permissions:
issues: write
jobs:
publish-node:
name: Publish Custom Node to registry
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'pydn' }}
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Publish Custom Node
uses: Comfy-Org/publish-node-action@v1
with:
## Add your own personal access token to your Github Repository secrets and reference it here.
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
+18 -2
View File
@@ -11,7 +11,8 @@ from argparse import ArgumentParser
import black
# Add current directory to Python path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from comfyui_to_python_utils import (
import_custom_nodes,
find_path,
@@ -211,8 +212,18 @@ class CodeGenerator:
for idx, data, is_special_function in load_order:
# Generate class definition and inputs from the data
inputs, class_type = data["inputs"], data["class_type"]
input_types = self.node_class_mappings[class_type].INPUT_TYPES()
class_def = self.node_class_mappings[class_type]()
# If required inputs are not present, skip the node as it will break the code if passed through to the script
missing_required_variable = False
if "required" in input_types.keys():
for required in input_types["required"]:
if required not in inputs.keys():
missing_required_variable = True
if missing_required_variable:
continue
# If the class hasn't been initialized yet, initialize it and generate the import statements
if class_type not in initialized_objects:
# No need to use preview image nodes since we are executing the script in a terminal
@@ -242,7 +253,12 @@ class CodeGenerator:
if no_params or key in class_def_params
}
# Deal with hidden variables
if class_def_params is not None:
if (
"hidden" in input_types.keys()
and "unique_id" in input_types["hidden"].keys()
):
inputs["unique_id"] = random.randint(1, 2**64)
elif class_def_params is not None:
if "unique_id" in class_def_params:
inputs["unique_id"] = random.randint(1, 2**64)
+2 -1
View File
@@ -12,6 +12,7 @@ def import_custom_nodes() -> None:
import asyncio
import execution
from nodes import init_extra_nodes
sys.path.insert(0, find_path("ComfyUI"))
import server
# Creating a new event loop and setting it as the default loop
@@ -23,7 +24,7 @@ def import_custom_nodes() -> None:
execution.PromptQueue(server_instance)
# Initializing custom nodes
init_extra_nodes()
asyncio.run(init_extra_nodes())
def find_path(name: str, path: str = None) -> str:
+48 -44
View File
@@ -1,56 +1,60 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js";
import { app } from "../../scripts/app.js";
import { $el } from "../../scripts/ui.js";
app.registerExtension({
const extension = {
name: "Comfy.SaveAsScript",
commands: [
{
id: "triggerSaveAsScript",
label: "Save As Script",
function: () => { extension.savePythonScript(); }
}
],
menuCommands: [
{
path: ["File"],
commands: ["triggerSaveAsScript"]
}
],
init() {
$el("style", {
parent: document.head,
});
},
async setup() {
const menu = document.querySelector(".comfy-menu");
const separator = document.createElement("hr");
separator.style.margin = "20px 0";
separator.style.width = "100%";
menu.append(separator);
const saveButton = document.createElement("button");
saveButton.textContent = "Save as Script";
saveButton.onclick = () => {
var filename = prompt("Save script as:");
if(filename === undefined || filename === null || filename === "") {
return
}
app.graphToPrompt().then(async (p) => {
const json = JSON.stringify({name: filename + ".json", workflow: JSON.stringify(p.output, null, 2)}, null, 2); // convert the data to a JSON string
var response = await api.fetchApi(`/saveasscript`, { method: "POST", body: json });
if(response.status == 200) {
const blob = new Blob([await response.text()], {type: "text/python;charset=utf-8"});
const url = URL.createObjectURL(blob);
if(!filename.endsWith(".py")) {
filename += ".py";
}
const a = $el("a", {
href: url,
download: filename,
style: {display: "none"},
parent: document.body,
});
a.click();
setTimeout(function () {
a.remove();
window.URL.revokeObjectURL(url);
}, 0);
}
});
}
menu.append(saveButton);
savePythonScript() {
var filename = prompt("Save script as:");
if(filename === undefined || filename === null || filename === "") {
return
}
app.graphToPrompt().then(async (p) => {
const json = JSON.stringify({name: filename + ".json", workflow: JSON.stringify(p.output, null, 2)}, null, 2); // convert the data to a JSON string
var response = await api.fetchApi(`/saveasscript`, { method: "POST", body: json });
if(response.status == 200) {
const blob = new Blob([await response.text()], {type: "text/python;charset=utf-8"});
const url = URL.createObjectURL(blob);
if(!filename.endsWith(".py")) {
filename += ".py";
}
const a = $el("a", {
href: url,
download: filename,
style: {display: "none"},
parent: document.body,
});
a.click();
setTimeout(function () {
a.remove();
window.URL.revokeObjectURL(url);
}, 0);
}
});
},
async setup() {
console.log("SaveAsScript loaded");
}
});
};
app.registerExtension(extension);
+15
View File
@@ -0,0 +1,15 @@
[project]
name = "comfyui-to-python-extension"
description = "This custom node allows you to generate pure python code from your ComfyUI workflow with the click of a button. Great for rapid experimentation or production deployment."
version = "1.3.1"
license = { text = "MIT License" }
dependencies = ["black"]
[project.urls]
Repository = "https://github.com/pydn/ComfyUI-to-Python-Extension"
# Used by Comfy Registry https://comfyregistry.org
[tool.comfy]
PublisherId = "pydn"
DisplayName = "ComfyUI-to-Python-Extension"
Icon = ""