Skip to content

Commit d6c5b11

Browse files
authored
Merge pull request #152 from pydn/cluster-2-compatibility-78-99-137
Clarify Python support and harden export/install compatibility
2 parents 228c3a0 + 5d70efd commit d6c5b11

File tree

4 files changed

+44
-22
lines changed

4 files changed

+44
-22
lines changed

__init__.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,10 @@
1313
try:
1414
import black
1515
except ImportError:
16-
print("Unable to import requirements for ComfyUI-SaveAsScript.")
17-
print("Installing...")
18-
19-
import importlib
20-
21-
spec = importlib.util.spec_from_file_location(
22-
"impact_install", os.path.join(os.path.dirname(__file__), "install.py")
23-
)
24-
impact_install = importlib.util.module_from_spec(spec)
25-
spec.loader.exec_module(impact_install)
26-
27-
print("Successfully installed. Hopefully, at least.")
16+
raise ImportError(
17+
"ComfyUI-to-Python-Extension requires the project dependencies to be installed. "
18+
f"Run 'uv sync' in {ext_dir} with Python 3.12+ before loading this extension."
19+
) from None
2820

2921
# Prevent reimporting of custom nodes
3022
os.environ["RUNNING_IN_COMFYUI"] = "TRUE"

js/save-as-script.js

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { api } from "../../scripts/api.js";
22
import { app } from "../../scripts/app.js";
33

4+
const DEFAULT_SCRIPT_FILENAME = "workflow_api.py";
5+
const DEFAULT_WORKFLOW_NAME = "workflow_api.json";
6+
47
function $el(tag, options = {}) {
58
const element = document.createElement(tag);
69
const { parent, style, ...props } = options;
@@ -39,26 +42,19 @@ const extension = {
3942
});
4043
},
4144
savePythonScript() {
42-
var filename = prompt("Save script as:");
43-
if(filename === undefined || filename === null || filename === "") {
44-
return
45-
}
46-
45+
const filename = DEFAULT_SCRIPT_FILENAME;
46+
4747
app.graphToPrompt().then(async (p) => {
4848
const frontendWorkflow = p.workflow ?? app.graph.serialize();
4949
const json = JSON.stringify({
50-
name: filename + ".json",
50+
name: DEFAULT_WORKFLOW_NAME,
5151
workflow: JSON.stringify(p.output, null, 2),
5252
frontend_workflow: JSON.stringify(frontendWorkflow, null, 2),
5353
}, null, 2); // convert the data to a JSON string
5454
var response = await api.fetchApi(`/saveasscript`, { method: "POST", body: json });
5555
if(response.status == 200) {
5656
const blob = new Blob([await response.text()], {type: "text/python;charset=utf-8"});
5757
const url = URL.createObjectURL(blob);
58-
if(!filename.endsWith(".py")) {
59-
filename += ".py";
60-
}
61-
6258
const a = $el("a", {
6359
href: url,
6460
download: filename,

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ name = "comfyui-to-python-extension"
33
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."
44
version = "2.0.0"
55
license = { text = "MIT License" }
6+
requires-python = ">=3.12"
67
dependencies = ["black"]
78

89
[project.urls]

tests/test_project_contracts.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import tomllib
2+
import unittest
3+
from pathlib import Path
4+
5+
6+
REPO_ROOT = Path(__file__).resolve().parent.parent
7+
8+
9+
class ProjectContractsTest(unittest.TestCase):
10+
def test_project_declares_supported_python_floor(self):
11+
pyproject = tomllib.loads((REPO_ROOT / "pyproject.toml").read_text(encoding="utf-8"))
12+
13+
self.assertEqual(pyproject["project"]["requires-python"], ">=3.12")
14+
15+
def test_readme_documents_python_support_and_default_save_filename(self):
16+
readme = (REPO_ROOT / "README.md").read_text(encoding="utf-8")
17+
18+
self.assertIn("This project supports Python 3.12 and newer.", readme)
19+
self.assertIn("default filename `workflow_api.py`", readme)
20+
21+
def test_extension_import_path_requires_uv_sync_instead_of_running_install_py(self):
22+
init_text = (REPO_ROOT / "__init__.py").read_text(encoding="utf-8")
23+
24+
self.assertIn("Run 'uv sync'", init_text)
25+
self.assertNotIn("spec_from_file_location", init_text)
26+
self.assertNotIn("Successfully installed. Hopefully, at least.", init_text)
27+
28+
def test_frontend_save_flow_uses_deterministic_filename_without_prompt(self):
29+
save_as_script = (REPO_ROOT / "js" / "save-as-script.js").read_text(encoding="utf-8")
30+
31+
self.assertIn('const DEFAULT_SCRIPT_FILENAME = "workflow_api.py";', save_as_script)
32+
self.assertNotIn("prompt(", save_as_script)
33+

0 commit comments

Comments
 (0)