├── .gitignore
├── README.md
├── out
└── sample.png
├── package.json
└── src
├── 01_api_basic.js
├── 02_api_getHistory.js
├── 03_api_getImage.js
├── 04_api_interrupt.js
├── 05_ws_basic.js
├── 06_ws_simple_message.js
├── 07_ws_message.js
├── 08_api_ws.js
├── 09_bonus.js
├── api
├── config.js
├── getImagePNG.js
├── interrupt.js
└── postQueue.js
├── config.js
├── utils
└── index.js
└── workflow
└── 01_workflow_api_basic.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 | .pnpm-debug.log*
9 | package-lock.json
10 |
11 | # Dependency directories
12 | node_modules/
13 |
14 | # Optional npm cache directory
15 | .npm
16 |
17 | # dotenv environment variable files
18 | .env
19 | .env.development.local
20 | .env.test.local
21 | .env.production.local
22 | .env.local
23 |
24 | # Sandbox
25 | sandbox
26 |
27 | # yarn v2
28 | .yarn/cache
29 | .yarn/unplugged
30 | .yarn/build-state.yml
31 | .yarn/install-state.gz
32 | .pnp.*
33 |
34 | # Mac
35 | .DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ComfyUI-API-WS
2 | Example for how to communicate with ComfyUI via API and Websocket
3 |
4 | # How to use
5 |
6 | clone this repo
7 |
8 | `git clone https://github.com/4rmx/comfyui-api-ws`
9 |
10 | and install dependency
11 |
12 | `npm install`
13 |
14 | or
15 |
16 | `yarn install`
17 |
18 | this workflow required costom_node `https://github.com/BlenderNeko/ComfyUI_ADV_CLIP_emb`
19 |
20 | start ComfyUI server
21 |
22 | You may use args `--listen` if you want to make the server listen to network connections.
23 |
24 | or use args `--port` to make the server listen on a specific port.
25 |
26 | and then change your ComfyUI server endpoint at file `/src/config`
27 |
28 | feel free to navigate the example eg.
29 | `node src/01_api_basic.js`
30 | # support me
31 |
32 |
33 |
--------------------------------------------------------------------------------
/out/sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/4rmx/comfyui-api-ws/3da7a47cb29bc4199e3d01a0a72a6c2b34af7425/out/sample.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "comfyui-api-ws",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/4rmx/comfyui-api-ws.git"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "bugs": {
17 | "url": "https://github.com/4rmx/comfyui-api-ws/issues"
18 | },
19 | "homepage": "https://github.com/4rmx/comfyui-api-ws#readme",
20 | "dependencies": {
21 | "axios": "^0.27.2",
22 | "cli-progress": "^3.12.0",
23 | "uuid": "^9.0.1",
24 | "ws": "^8.14.2"
25 | }
26 | }
--------------------------------------------------------------------------------
/src/01_api_basic.js:
--------------------------------------------------------------------------------
1 | const { default: axios } = require('axios');
2 | const { COMFYUI_API_ENDPOINT } = require('./config');
3 | const wf = require('./workflow/01_workflow_api_basic.json');
4 |
5 | async function executePrompt() {
6 | try {
7 | // change positive prompt
8 | wf[3].inputs.text = '1girl';
9 |
10 | // change file name in save image node
11 | wf[7].inputs.filename_prefix = 'sample';
12 |
13 | // log workflow befor send
14 | console.log(wf);
15 |
16 | // send to api
17 | const response = await axios.post(`http://${COMFYUI_API_ENDPOINT}/prompt`, { prompt: wf });
18 |
19 | /** @type {import('./api/postQueue').ResponseSuccess} */
20 | const data = response.data;
21 |
22 | // response prompt_id
23 | console.log('prompt_id:', data.prompt_id);
24 | } catch (err) {
25 | console.log(err);
26 | }
27 | }
28 |
29 | executePrompt();
--------------------------------------------------------------------------------
/src/02_api_getHistory.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef Images
3 | * @property {string} filename
4 | * @property {string} subfolder
5 | * @property {string} type
6 | *
7 | * @typedef {Object. }>} Outputs
8 | *
9 | * @typedef {Object.} ResponseSuccess
10 | */
11 |
12 | const { default: axios } = require('axios');
13 | const { COMFYUI_API_ENDPOINT } = require('./config');
14 |
15 | // replace prompt_id from 01_basic_api response
16 | const prompt_id = 'c32003af-9d4a-44c6-97a0-89b20f0e4dac';
17 |
18 | async function getHistory() {
19 | try {
20 | const response = await axios.get(`http://${COMFYUI_API_ENDPOINT}/history/${prompt_id}`);
21 |
22 | /** @type {ResponseSuccess} */
23 | const data = response.data;
24 |
25 | // console.log(data[prompt_id]);
26 | console.log(data[prompt_id].outputs['7'].images);
27 | } catch (err) {
28 | console.log(err);
29 | }
30 | }
31 |
32 | getHistory();
--------------------------------------------------------------------------------
/src/03_api_getImage.js:
--------------------------------------------------------------------------------
1 | const { default: axios } = require('axios');
2 | const fs = require('fs');
3 | const { COMFYUI_API_ENDPOINT } = require('./config');
4 |
5 | // file name and subfolder from
6 | const output = { filename: 'sample_00001_.png', subfolder: '', type: 'output' };
7 |
8 | async function getImage() {
9 | try {
10 | // parse output object to url params
11 | const params = new URLSearchParams(output).toString();
12 |
13 | // send request with specific resposponseType specific for save .png with fs
14 | const response = await axios.get(`http://${COMFYUI_API_ENDPOINT}/view?${params}`, { responseType: 'arraybuffer' });
15 |
16 | // save png image
17 | fs.writeFileSync(`out/${output.filename}`, response.data);
18 | } catch (err) {
19 | console.log(err);
20 | }
21 | }
22 |
23 | getImage();
--------------------------------------------------------------------------------
/src/04_api_interrupt.js:
--------------------------------------------------------------------------------
1 | const { default: axios } = require('axios');
2 | const { COMFYUI_API_ENDPOINT } = require('./config');
3 |
4 | // send api when you need to interrupt comfyUI execution
5 | async function interrupt() {
6 | try {
7 | const response = await axios.post(`http://${COMFYUI_API_ENDPOINT}/interrupt`);
8 | console.log(response.status);
9 | } catch (err) {
10 | console.log(err);
11 | }
12 | }
13 |
14 | interrupt();
--------------------------------------------------------------------------------
/src/05_ws_basic.js:
--------------------------------------------------------------------------------
1 | const { v4: uuidv4 } = require('uuid');
2 | const { WebSocket } = require('ws');
3 | const { COMFYUI_API_ENDPOINT } = require('./config');
4 |
5 | const client_id = uuidv4();
6 |
7 | // Create Websocket instant
8 | const ws = new WebSocket(`ws://${COMFYUI_API_ENDPOINT}/ws?clientId=${client_id}`);
9 |
10 | // log when error
11 | ws.on('error', console.error);
12 |
13 | // log when socket connected
14 | ws.on('open', () => console.log('socket is connected!'));
--------------------------------------------------------------------------------
/src/06_ws_simple_message.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef MessageStatus
3 | * @property {'status'} type
4 | * @property {object} data
5 | * @property {object} data.status
6 | * @property {object} data.status.exec_info
7 | * @property {number} data.status.exec_info.queue_remaining
8 | */
9 | const { v4: uuidv4 } = require('uuid');
10 | const { WebSocket } = require('ws');
11 | const { COMFYUI_API_ENDPOINT } = require('./config');
12 |
13 | // Create ClientId
14 | const client_id = uuidv4();
15 |
16 | // Create Websocket instant
17 | const ws = new WebSocket(`ws://${COMFYUI_API_ENDPOINT}/ws?clientId=${client_id}`);
18 |
19 | // log when error
20 | ws.on('error', console.error);
21 |
22 | // handle incomming message from websocket
23 | ws.on('message', handleComfyUIMessage);
24 |
25 | // log when socket connected
26 | ws.on('open', () => console.log('socket is connected!'));
27 |
28 | /** @param {string} msg */
29 | async function handleComfyUIMessage(msg) {
30 | try {
31 | msg = JSON.parse(msg);
32 | if (msg?.type === 'status') {
33 | /** @type {MessageStatus} */
34 | const { data } = msg;
35 | console.log(data.status.exec_info);
36 | } else {
37 | console.log(msg);
38 | }
39 | } catch (err) {
40 | console.log(err);
41 | }
42 | }
--------------------------------------------------------------------------------
/src/07_ws_message.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {'status'|'progress'|'executing'|'executed'|'execution_start'|'execution_error'|'execution_cached'} MessageType
3 | *
4 | * @typedef MsgStatus
5 | * @property {'status'} type
6 | * @property {object} data
7 | * @property {object} data.status
8 | * @property {object} data.status.exec_info
9 | * @property {number} data.status.exec_info.queue_remaining
10 | *
11 | * @typedef MsgExeStart
12 | * @property {string} type
13 | * @property {object} data
14 | * @property {string} data.prompt_id
15 | *
16 | * @typedef MsgExeCached
17 | * @property {string} type
18 | * @property {object} data
19 | * @property {} data.nodes
20 | * @property {string} data.prompt_id
21 | *
22 | * @typedef MsgExe
23 | * @property {string} type
24 | * @property {object} data
25 | * @property {string|null} data.node
26 | * @property {string} data.prompt_id
27 | *
28 | * @typedef MsgProgress
29 | * @property {string} type
30 | * @property {object} data
31 | * @property {number} data.value
32 | * @property {number} data.max
33 | *
34 | * @typedef MsgExecuted
35 | * @property {string} type
36 | * @property {object} data
37 | * @property {string} data.node
38 | * @property {object} data.output
39 | * @property {object[]} data.output.images
40 | * @property {string} data.output.images.filename
41 | * @property {string} data.output.images.subfolder
42 | * @property {string} data.output.images.type
43 | * @property {string} data.prompt_id
44 | */
45 |
46 | const { v4: uuidv4 } = require('uuid');
47 | const { WebSocket } = require('ws');
48 | const fs = require('fs');
49 | const { COMFYUI_API_ENDPOINT } = require('./config');
50 | const wf = require('./workflow/01_workflow_api_basic.json');
51 | const postQueue = require('./api/postQueue');
52 | const getImagePNG = require('./api/getImagePNG');
53 |
54 | // Create ClientId
55 | const client_id = uuidv4();
56 |
57 | // Create Websocket instant
58 | const ws = new WebSocket(`ws://${COMFYUI_API_ENDPOINT}/ws?clientId=${client_id}`);
59 |
60 | // log when error
61 | ws.on('error', console.error);
62 |
63 | // handle incomming message from websocket
64 | ws.on('message', handleComfyUIMessage);
65 |
66 | // when socket connected
67 | ws.on('open', () => {
68 | console.log('socket is connected!');
69 | queuePrompt();
70 | });
71 |
72 | /** @param {string} msg */
73 | function handleComfyUIMessage(msg) {
74 | msg = JSON.parse(msg);
75 | /** @type {MessageType} */
76 | const type = msg?.type;
77 | if (type === 'status') {
78 | /** @type {MsgStatus} */
79 | const { data } = msg;
80 | // console.log(data.status.exec_info);
81 | const { queue_remaining } = data.status.exec_info;
82 | console.log({ queue_remaining });
83 | } else if (type === 'execution_start') {
84 | /** @type {MsgExeStart} */
85 | const { data } = msg;
86 | console.log('prompt_id:', data.prompt_id);
87 | } else if (type === 'executing') {
88 | /** @type {MsgExe} */
89 | const { data } = msg;
90 | // when all execution is done and queue is available
91 | if (data.node === null) {
92 | console.log('DONE!');
93 | } else {
94 | console.log(data);
95 | }
96 | } else if (type === 'executed') {
97 | // when execution is done
98 | /** @type {MsgExecuted} */
99 | const { data } = msg;
100 | console.log(data.output.images);
101 | handleDownloadImage(data.output.images[0]);
102 | } else {
103 | console.log(msg);
104 | }
105 | };
106 |
107 | async function queuePrompt() {
108 | try {
109 | const res = await postQueue(wf, client_id);
110 | console.log(res.data);
111 | } catch (err) {
112 | console.log(err);
113 | }
114 | }
115 |
116 | /**
117 | * @typedef Image
118 | * @property {string} filename
119 | * @property {string} subfolder
120 | * @property {string} type
121 | *
122 | * @param {Image} image
123 | */
124 | async function handleDownloadImage(image) {
125 | try {
126 | const params = new URLSearchParams(image);
127 | const response = await getImagePNG(params);
128 | fs.writeFileSync(`out/${image.filename}`, response.data);
129 | console.log('Downloaded!');
130 | } catch (err) {
131 | console.log(err);
132 | }
133 | }
134 |
135 |
--------------------------------------------------------------------------------
/src/08_api_ws.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {'status'|'progress'|'executing'|'executed'|'execution_start'|'execution_error'|'execution_cached'} MessageType
3 | *
4 | * @typedef MsgStatus
5 | * @property {'status'} type
6 | * @property {object} data
7 | * @property {object} data.status
8 | * @property {object} data.status.exec_info
9 | * @property {number} data.status.exec_info.queue_remaining
10 | *
11 | * @typedef MsgExeStart
12 | * @property {string} type
13 | * @property {object} data
14 | * @property {string} data.prompt_id
15 | *
16 | * @typedef MsgExeCached
17 | * @property {string} type
18 | * @property {object} data
19 | * @property {} data.nodes
20 | * @property {string} data.prompt_id
21 | *
22 | * @typedef MsgExe
23 | * @property {string} type
24 | * @property {object} data
25 | * @property {string|null} data.node
26 | * @property {string} data.prompt_id
27 | *
28 | * @typedef MsgProgress
29 | * @property {string} type
30 | * @property {object} data
31 | * @property {number} data.value
32 | * @property {number} data.max
33 | *
34 | * @typedef MsgExecuted
35 | * @property {string} type
36 | * @property {object} data
37 | * @property {string} data.node
38 | * @property {object} data.output
39 | * @property {object[]} data.output.images
40 | * @property {string} data.output.images.filename
41 | * @property {string} data.output.images.subfolder
42 | * @property {string} data.output.images.type
43 | * @property {string} data.prompt_id
44 | */
45 |
46 | const { v4: uuidv4 } = require('uuid');
47 | const { WebSocket } = require('ws');
48 | const fs = require('fs');
49 | const { COMFYUI_API_ENDPOINT } = require('./config');
50 | const wf = require('./workflow/01_workflow_api_basic.json');
51 | const postQueue = require('./api/postQueue');
52 | const getImagePNG = require('./api/getImagePNG');
53 |
54 | // Create ClientId
55 | const client_id = uuidv4();
56 |
57 | // Create Websocket instant
58 | const ws = new WebSocket(`ws://${COMFYUI_API_ENDPOINT}/ws?clientId=${client_id}`);
59 |
60 | // log when error
61 | ws.on('error', console.error);
62 |
63 | // handle incomming message from websocket
64 | ws.on('message', handleComfyUIMessage);
65 |
66 | // when socket connected
67 | ws.on('open', () => {
68 | console.log('socket is connected!');
69 | // start queue prompt when socket is connected!
70 | queuePrompt();
71 | });
72 |
73 | /** @param {string} msg */
74 | function handleComfyUIMessage(msg) {
75 | msg = JSON.parse(msg);
76 | /** @type {MessageType} */
77 | const type = msg?.type;
78 | if (type === 'status') {
79 | /** @type {MsgStatus} */
80 | const { data } = msg;
81 | // console.log(data.status.exec_info);
82 | const { queue_remaining } = data.status.exec_info;
83 | console.log({ queue_remaining });
84 | } else if (type === 'execution_start') {
85 | /** @type {MsgExeStart} */
86 | const { data } = msg;
87 | console.log('prompt_id:', data.prompt_id);
88 | } else if (type === 'executing') {
89 | /** @type {MsgExe} */
90 | const { data } = msg;
91 | // when all execution is done and queue is available
92 | if (data.node === null) {
93 | console.log('DONE!');
94 | } else {
95 | console.log(data);
96 | }
97 | } else if (type === 'executed') {
98 | // when execution is done
99 | /** @type {MsgExecuted} */
100 | const { data } = msg;
101 | console.log(data.output.images);
102 | handleDownloadImage(data.output.images[0]);
103 | } else {
104 | console.log(msg);
105 | }
106 | };
107 |
108 | async function queuePrompt() {
109 | try {
110 | const res = await postQueue(wf, client_id);
111 | console.log(res.data);
112 | } catch (err) {
113 | console.log(err);
114 | }
115 | }
116 |
117 | /**
118 | * @typedef Image
119 | * @property {string} filename
120 | * @property {string} subfolder
121 | * @property {string} type
122 | *
123 | * @param {Image} image
124 | */
125 | async function handleDownloadImage(image) {
126 | try {
127 | const params = new URLSearchParams(image);
128 | const response = await getImagePNG(params);
129 | fs.writeFileSync(`out/${image.filename}`, response.data);
130 | console.log('Downloaded!');
131 | } catch (err) {
132 | console.log(err);
133 | }
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/src/09_bonus.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @typedef {'status'|'progress'|'executing'|'executed'|'execution_start'|'execution_error'|'execution_cached'} MessageType
3 | *
4 | * @typedef MsgStatus
5 | * @property {'status'} type
6 | * @property {object} data
7 | * @property {object} data.status
8 | * @property {object} data.status.exec_info
9 | * @property {number} data.status.exec_info.queue_remaining
10 | *
11 | * @typedef MsgExeStart
12 | * @property {string} type
13 | * @property {object} data
14 | * @property {string} data.prompt_id
15 | *
16 | * @typedef MsgExeCached
17 | * @property {string} type
18 | * @property {object} data
19 | * @property {} data.nodes
20 | * @property {string} data.prompt_id
21 | *
22 | * @typedef MsgExe
23 | * @property {string} type
24 | * @property {object} data
25 | * @property {string|null} data.node
26 | * @property {string} data.prompt_id
27 | *
28 | * @typedef MsgProgress
29 | * @property {string} type
30 | * @property {object} data
31 | * @property {number} data.value
32 | * @property {number} data.max
33 | *
34 | * @typedef MsgExecuted
35 | * @property {string} type
36 | * @property {object} data
37 | * @property {string} data.node
38 | * @property {object} data.output
39 | * @property {object[]} data.output.images
40 | * @property {string} data.output.images.filename
41 | * @property {string} data.output.images.subfolder
42 | * @property {string} data.output.images.type
43 | * @property {string} data.prompt_id
44 | */
45 |
46 | const { v4: uuidv4 } = require('uuid');
47 | const { WebSocket } = require('ws');
48 | const fs = require('fs');
49 | const cliProgress = require('cli-progress');
50 |
51 | const { COMFYUI_API_ENDPOINT } = require('./config');
52 | const wf = require('./workflow/01_workflow_api_basic.json');
53 | const postQueue = require('./api/postQueue');
54 | const getImagePNG = require('./api/getImagePNG');
55 | const { randomSeed } = require('./utils');
56 |
57 | // Create ClientId
58 | const client_id = uuidv4();
59 |
60 | // Create Websocket instant
61 | const ws = new WebSocket(`ws://${COMFYUI_API_ENDPOINT}/ws?clientId=${client_id}`);
62 |
63 | // create simple progress bar
64 | const bar1 = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
65 |
66 | // log when error
67 | ws.on('error', console.error);
68 |
69 | // handle incomming message from websocket
70 | ws.on('message', handleComfyUIMessage);
71 |
72 | // when socket connected
73 | ws.on('open', () => {
74 | console.log('socket is connected!');
75 | // start queue prompt when socket is connected!
76 | queuePrompt();
77 | });
78 |
79 | /** @param {string} msg */
80 | function handleComfyUIMessage(msg) {
81 | msg = JSON.parse(msg);
82 | /** @type {MessageType} */
83 | const type = msg?.type;
84 | if (type === 'status') {
85 | /** @type {MsgStatus} */
86 | const { data } = msg;
87 | // console.log(data.status.exec_info);
88 | const { queue_remaining } = data.status.exec_info;
89 | console.log({ queue_remaining });
90 | } else if (type === 'execution_start') {
91 | /** @type {MsgExeStart} */
92 | const { data } = msg;
93 | console.log('prompt_id:', data.prompt_id);
94 | } else if (type === 'executing') {
95 | /** @type {MsgExe} */
96 | const { data } = msg;
97 | // when all execution is done and queue is available
98 | if (data.node === null) {
99 | console.log('DONE!');
100 | } else {
101 | console.log(data);
102 | }
103 | } else if (type === 'executed') {
104 | // when execution is done
105 | /** @type {MsgExecuted} */
106 | const { data } = msg;
107 | console.log(data.output.images);
108 | handleDownloadImage(data.output.images[0]);
109 | } else if (type === 'progress') {
110 | // when sampler progress use progress bar to show status
111 | /** @type {MsgProgress} */
112 | const { data } = msg;
113 | if (bar1.getProgress() === 0) {
114 | bar1.start(data.max, data.value);
115 | } else if (data.max === data.value) {
116 | bar1.update(data.value);
117 | bar1.stop();
118 | } else {
119 | bar1.update(data.value);
120 | }
121 | } else {
122 | console.log(msg);
123 | }
124 | };
125 |
126 | async function queuePrompt() {
127 | try {
128 | // manual random seed by js code;
129 | wf[2].inputs.seed = randomSeed();
130 | const res = await postQueue(wf, client_id);
131 | console.log(res.data);
132 | } catch (err) {
133 | console.log(err);
134 | }
135 | }
136 |
137 | /**
138 | * @typedef Image
139 | * @property {string} filename
140 | * @property {string} subfolder
141 | * @property {string} type
142 | *
143 | * @param {Image} image
144 | */
145 | async function handleDownloadImage(image) {
146 | try {
147 | const params = new URLSearchParams(image);
148 | const response = await getImagePNG(params);
149 | fs.writeFileSync(`out/${image.filename}`, response.data);
150 | console.log('Downloaded!');
151 | } catch (err) {
152 | console.log(err);
153 | }
154 | }
155 |
156 |
--------------------------------------------------------------------------------
/src/api/config.js:
--------------------------------------------------------------------------------
1 | const { default: baseAxios } = require('axios');
2 | const { COMFYUI_API_ENDPOINT } = require('../config');
3 |
4 | const comfyAPI = baseAxios.create({ baseURL: 'http://' + COMFYUI_API_ENDPOINT });
5 |
6 | module.exports = { comfyAPI };
--------------------------------------------------------------------------------
/src/api/getImagePNG.js:
--------------------------------------------------------------------------------
1 | const { comfyAPI } = require('./config');
2 |
3 | /** @param {string} params */
4 | module.exports = (params) => comfyAPI.get(`view?${params}`, { responseType: 'arraybuffer' });
5 |
--------------------------------------------------------------------------------
/src/api/interrupt.js:
--------------------------------------------------------------------------------
1 | const { comfyAPI } = require('./config');
2 |
3 | async function execute() {
4 | return comfyAPI.post('/interrupt')
5 | .then(res => {
6 | console.log(res.statusText);
7 | return res;
8 | })
9 | .catch(err => {
10 | console.log(err);
11 | });
12 | }
13 |
14 | execute();
--------------------------------------------------------------------------------
/src/api/postQueue.js:
--------------------------------------------------------------------------------
1 | const { comfyAPI } = require('./config');
2 |
3 | /**
4 | * @typedef ResponseSuccess
5 | * @property {string} prompt_id
6 | * @property {number} number
7 | * @property {object} node_errors
8 | */
9 |
10 | /**
11 | * @param {Object.} prompt
12 | * @param {string} client_id
13 | * @return {Promise>}
14 | */
15 | module.exports = (prompt, client_id) => comfyAPI.post('prompt', { prompt, client_id });
16 |
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | // configure your comfyui endpoint url here
2 | // for default local comfyui should be like 127.0.0.1:8188 or 192.168.0.1:8188
3 | module.exports = {
4 | COMFYUI_API_ENDPOINT: 'comfy.win:8188'
5 | };
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | function countDecimals(value) {
2 | if (Math.floor(value) === value) return 0;
3 | return value.toString().split(".")[1].length || 0;
4 | }
5 |
6 | function addZero(count) {
7 | let txt = '1';
8 | for (let i = 0; i < count; i++) {
9 | txt += '0';
10 | }
11 | return Number(txt);
12 | }
13 |
14 | function randomSeed() {
15 | const rand = Math.random();
16 | const count = countDecimals(rand);
17 | return Math.floor(rand * addZero(count));
18 | }
19 |
20 | module.exports = { randomSeed };
--------------------------------------------------------------------------------
/src/workflow/01_workflow_api_basic.json:
--------------------------------------------------------------------------------
1 | {
2 | "1": {
3 | "inputs": {
4 | "ckpt_name": "epicphotogasm_x.safetensors"
5 | },
6 | "class_type": "CheckpointLoaderSimple"
7 | },
8 | "2": {
9 | "inputs": {
10 | "seed": 408337996593045,
11 | "steps": 20,
12 | "cfg": 7,
13 | "sampler_name": "dpmpp_2m_sde",
14 | "scheduler": "karras",
15 | "denoise": 1,
16 | "model": [
17 | "1",
18 | 0
19 | ],
20 | "positive": [
21 | "3",
22 | 0
23 | ],
24 | "negative": [
25 | "4",
26 | 0
27 | ],
28 | "latent_image": [
29 | "5",
30 | 0
31 | ]
32 | },
33 | "class_type": "KSampler"
34 | },
35 | "3": {
36 | "inputs": {
37 | "text": "a cup of coffee, hot, (steam:0.1)",
38 | "clip": [
39 | "1",
40 | 1
41 | ]
42 | },
43 | "class_type": "CLIPTextEncode"
44 | },
45 | "4": {
46 | "inputs": {
47 | "text": "(worst quality, low quality, normal quality:1.25), lowres, jpeg artifacts, watermark, paintings, sketches, cartoons, illustration, 3d,",
48 | "clip": [
49 | "1",
50 | 1
51 | ]
52 | },
53 | "class_type": "CLIPTextEncode"
54 | },
55 | "5": {
56 | "inputs": {
57 | "width": 512,
58 | "height": 768,
59 | "batch_size": 1
60 | },
61 | "class_type": "EmptyLatentImage"
62 | },
63 | "6": {
64 | "inputs": {
65 | "samples": [
66 | "2",
67 | 0
68 | ],
69 | "vae": [
70 | "1",
71 | 2
72 | ]
73 | },
74 | "class_type": "VAEDecode"
75 | },
76 | "7": {
77 | "inputs": {
78 | "filename_prefix": "coffee",
79 | "images": [
80 | "6",
81 | 0
82 | ]
83 | },
84 | "class_type": "SaveImage"
85 | }
86 | }
--------------------------------------------------------------------------------