comfyui-autograph 2.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. comfyui_autograph-2.0.0/LICENSE +21 -0
  2. comfyui_autograph-2.0.0/PKG-INFO +403 -0
  3. comfyui_autograph-2.0.0/README.md +385 -0
  4. comfyui_autograph-2.0.0/autograph/__init__.py +78 -0
  5. comfyui_autograph-2.0.0/autograph/__main__.py +6 -0
  6. comfyui_autograph-2.0.0/autograph/api.py +143 -0
  7. comfyui_autograph-2.0.0/autograph/cli.py +110 -0
  8. comfyui_autograph-2.0.0/autograph/comfyproc.py +201 -0
  9. comfyui_autograph-2.0.0/autograph/connection.py +280 -0
  10. comfyui_autograph-2.0.0/autograph/convert.py +2048 -0
  11. comfyui_autograph-2.0.0/autograph/dag.py +375 -0
  12. comfyui_autograph-2.0.0/autograph/defaults.py +89 -0
  13. comfyui_autograph-2.0.0/autograph/flowtree.py +3246 -0
  14. comfyui_autograph-2.0.0/autograph/inprocess.py +973 -0
  15. comfyui_autograph-2.0.0/autograph/map.py +463 -0
  16. comfyui_autograph-2.0.0/autograph/model_layer.py +46 -0
  17. comfyui_autograph-2.0.0/autograph/models.py +2461 -0
  18. comfyui_autograph-2.0.0/autograph/net.py +75 -0
  19. comfyui_autograph-2.0.0/autograph/origin.py +40 -0
  20. comfyui_autograph-2.0.0/autograph/pngmeta.py +107 -0
  21. comfyui_autograph-2.0.0/autograph/py.typed +0 -0
  22. comfyui_autograph-2.0.0/autograph/results.py +1399 -0
  23. comfyui_autograph-2.0.0/autograph/version.py +1 -0
  24. comfyui_autograph-2.0.0/autograph/ws.py +778 -0
  25. comfyui_autograph-2.0.0/comfyui_autograph.egg-info/PKG-INFO +403 -0
  26. comfyui_autograph-2.0.0/comfyui_autograph.egg-info/SOURCES.txt +30 -0
  27. comfyui_autograph-2.0.0/comfyui_autograph.egg-info/dependency_links.txt +1 -0
  28. comfyui_autograph-2.0.0/comfyui_autograph.egg-info/entry_points.txt +2 -0
  29. comfyui_autograph-2.0.0/comfyui_autograph.egg-info/requires.txt +3 -0
  30. comfyui_autograph-2.0.0/comfyui_autograph.egg-info/top_level.txt +2 -0
  31. comfyui_autograph-2.0.0/pyproject.toml +54 -0
  32. comfyui_autograph-2.0.0/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 chris
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,403 @@
1
+ Metadata-Version: 2.4
2
+ Name: comfyui-autograph
3
+ Version: 2.0.0
4
+ Summary: Pure Python automation for ComfyUI: convert workflows, submit jobs, fetch images—no GUI required
5
+ Author: Chris Reid
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/chrisdreid/comfyui-autograph
8
+ Project-URL: Documentation, https://github.com/chrisdreid/comfyui-autograph#readme
9
+ Project-URL: Repository, https://github.com/chrisdreid/comfyui-autograph
10
+ Project-URL: Issues, https://github.com/chrisdreid/comfyui-autograph/issues
11
+ Keywords: comfyui,automation,workflow,workflow.json,workflow-api,workflow-api.json,stable-diffusion,image-generation,nodes,renderables,flow,apiflow,pipeline,ml,ai,api
12
+ Requires-Python: >=3.7
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Provides-Extra: pillow
16
+ Requires-Dist: pillow; extra == "pillow"
17
+ Dynamic: license-file
18
+
19
+ <!-- Keep version below in sync with autograph/version.py -->
20
+ ```text
21
+ $$\ $$\
22
+ $$ | $$ |
23
+ $$$$$$\ $$\ $$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$$\
24
+ \____$$\ $$ | $$ |\_$$ _| $$ __$$\ $$ __$$\ $$ __$$\ \____$$\ $$ __$$\ $$ __$$\
25
+ $$$$$$$ |$$ | $$ | $$ | $$ / $$ |$$ / $$ |$$ | \__|$$$$$$$ |$$ / $$ |$$ | $$ |
26
+ $$ __$$ |$$ | $$ | $$ |$$\ $$ | $$ |$$ | $$ |$$ | $$ __$$ |$$ | $$ |$$ | $$ |
27
+ \$$$$$$$ |\$$$$$$ | \$$$$ |\$$$$$$ |\$$$$$$$ |$$ | \$$$$$$$ |$$$$$$$ |$$ | $$ |
28
+ \_______| \______/ \____/ \______/ \____$$ |\__| \_______|$$ ____/ \__| \__|
29
+ $$\ $$ | $$ |
30
+ \$$$$$$ | $$ |
31
+ \______/ \__|
32
+ ComfyUI version: 2.0.0
33
+ ```
34
+
35
+ [![PyPI version](https://img.shields.io/pypi/v/comfyui-autograph?color=blue)](https://pypi.org/project/comfyui-autograph/)
36
+ [![Python](https://img.shields.io/pypi/pyversions/comfyui-autograph)](https://pypi.org/project/comfyui-autograph/)
37
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/chrisdreid/comfyui-autograph/blob/main/LICENSE)
38
+ [![GitHub stars](https://img.shields.io/github/stars/chrisdreid/comfyui-autograph?style=social)](https://github.com/chrisdreid/comfyui-autograph)
39
+ [![GitHub issues](https://img.shields.io/github/issues/chrisdreid/comfyui-autograph)](https://github.com/chrisdreid/comfyui-autograph/issues)
40
+ [![Downloads](https://img.shields.io/pypi/dm/comfyui-autograph)](https://pypi.org/project/comfyui-autograph/)
41
+
42
+ ```mermaid
43
+ flowchart LR
44
+ workflowJson["workflow.json"] --> autograph["autograph"]
45
+ --> apiFlow[workflow-api.json]
46
+ ```
47
+ ---
48
+ # Imagine...
49
+ ### What if you could `load, edit, and submit` ComfyUI workflows without ever exporting an API workflow from the GUI?
50
+
51
+ ### What if you could `batch-convert and patch workflows offline` No running ComfyUI instance required?
52
+
53
+ ### What if you could attach studio `metadata` to your workflow and have it carry through the entire production lifecycle?
54
+
55
+ ### What if you could `render` comfyui node workflows with all of the above features, `without ever launching the comfyui server`?
56
+
57
+ - # Let me introduce `comfyui-autograph`
58
+
59
+ ---
60
+ # autograph
61
+
62
+ Skip the GUI. `autograph` handles the backend so you can automate/pipeline your ComfyUI renderables with full control through the entire conversion and submission process.
63
+ `autograph` is a small and efficient, pure **Python package** (stdlib-only +extendable) for ComfyUI automation that gives you access to renderable conversion with or without ComfyUI.
64
+
65
+ ## Features
66
+
67
+ | Feature | Description |
68
+ |---------|-------------|
69
+ | **Convert workflow.json** | `workflow.json` → renderable API payload, skip the GUI export entirely |
70
+ | **Offline / Online** | Convert without a running ComfyUI server, or fetch live from one |
71
+ | **Submit + Images** | Send to ComfyUI, wait for completion, fetch and save output images |
72
+ | **Progress** | Hook into WebSocket render events for real-time progress control |
73
+ | **Edit + Introspect** | `api.KSampler.seed = 42`, `.find(...)`, `.choices()`, `.tooltip()`. OOP access to every node and widget |
74
+ | **Metadata** | Attach studio metadata to workflows that carries through the entire production lifecycle |
75
+ | **Serverless Execute** | `.execute()` runs ComfyUI nodes in-process, no HTTP server required |
76
+ | **Map** | Sweep seeds, prompts, paths across nodes for batch pipelines |
77
+ | **Save + Load** | `.save()` / `.load()` on Flow, ApiFlow, and NodeInfo for simple serialization of any object |
78
+ | **Extract** | Load workflows directly from ComfyUI PNG outputs (embedded metadata) |
79
+ | **Stdlib-only** | Zero dependencies by default; optional Pillow, ImageMagick, ffmpeg |
80
+ | **Subgraphs** | Flattens nested `definitions.subgraphs` into a normal API payload |
81
+
82
+ ## Requirements
83
+
84
+ - Python 3.7+ (dict insertion order preserved)
85
+ - ComfyUI server (optional, for API mode)
86
+ - No additional Python packages required
87
+
88
+ ## Tested ComfyUI Versions:
89
+ - ComfyUI `0.8.2`
90
+ - ComfyUI_frontend `v1.35.9`
91
+
92
+ ---
93
+ ## The Two `ComfyUI Formats` you should know about
94
+
95
+ ComfyUI uses two JSON formats:
96
+
97
+ | Format | File | Description |
98
+ |--------|------|-------------|
99
+ | **Workspace** | `workflow.json` | The UI-editable graph with node positions, colors, widgets. What you save from ComfyUI. |
100
+ | **API Payload** | `workflow-api.json` | The renderable blueprint—just nodes + inputs, ready for `POST /prompt`. This is what `ApiFlow` represents. |
101
+
102
+ **autograph converts Workspace → API Payload** (or loads an existing API Payload directly).
103
+
104
+ ```mermaid
105
+ flowchart LR
106
+ workspace["workflow.json (workspace)"] --> convert["autograph"]
107
+ convert --> payload["workflow-api.json (API payload / ApiFlow)"]
108
+ payload --> submit["POST /prompt"]
109
+ submit --> comfy["ComfyUI renders"]
110
+ ```
111
+
112
+ ## Installation
113
+
114
+ ```bash
115
+ pip install comfyui-autograph
116
+ ```
117
+
118
+ Then use with `python -m autograph ...` or `import autograph` from Python.
119
+ - Optional: set `AUTOGRAPH_COMFYUI_SERVER_URL` once (then `server_url` / `--server-url` become optional):
120
+ - Linux/macOS: `export AUTOGRAPH_COMFYUI_SERVER_URL="http://localhost:8188"`
121
+ - Windows PowerShell: `$env:AUTOGRAPH_COMFYUI_SERVER_URL = "http://localhost:8188"`
122
+ - Windows CMD: `set AUTOGRAPH_COMFYUI_SERVER_URL=http://localhost:8188`
123
+ - Python: `import os; os.environ["AUTOGRAPH_COMFYUI_SERVER_URL"] = "http://localhost:8188"`
124
+ - Optional: set `AUTOGRAPH_NODE_INFO_SOURCE=modules|fetch|server|/path/to/node-info.json` to auto-resolve `node_info`.
125
+ ---
126
+ # `autograph` - Quick Start
127
+
128
+ ### Get `node-info.json` (optional, one-time)
129
+
130
+ Save `node-info.json` so you can convert offline. You can also convert against a running ComfyUI instance, but for efficiency we recommend pulling a new `node-info.json` per instance (reproducible, no server needed).
131
+
132
+ ```mermaid
133
+ flowchart LR
134
+ comfy["ComfyUI server"] --> obj["/object_info"]
135
+ obj --> file["node-info.json"]
136
+ ```
137
+
138
+ ```python
139
+ # api — set AUTOGRAPH_COMFYUI_SERVER_URL first (see Installation above)
140
+ from autograph import NodeInfo
141
+
142
+ node_info = NodeInfo('fetch')
143
+ node_info.save('node-info.json')
144
+ ```
145
+
146
+ ```bash
147
+ # cli
148
+ python -m autograph --download-node-info-path node-info.json
149
+ ```
150
+
151
+ - Direct modules (no server): `NodeInfo.from_comfyui_modules()` builds `node_info` from local ComfyUI nodes.
152
+ - Env source (optional): set `AUTOGRAPH_NODE_INFO_SOURCE=modules|fetch|server|/path/to/node-info.json`.
153
+
154
+ - More: [`docs/node-info-and-env.md`](docs/node-info-and-env.md)
155
+ ## Convert live (using running ComfyUI)
156
+
157
+ Convert `workflow.json` by fetching `/object_info` from your running ComfyUI server.
158
+
159
+ ```mermaid
160
+ flowchart LR
161
+ env["AUTOGRAPH_COMFYUI_SERVER_URL"] --> wf["Flow(...)"]
162
+ wf --> flow["Flow"]
163
+ comfy["ComfyUI server"] --> obj["/object_info"]
164
+ obj --> wf
165
+ ```
166
+ If environment variable `AUTOGRAPH_COMFYUI_SERVER_URL` is set, `server_url` becomes optional.
167
+
168
+ If `AUTOGRAPH_NODE_INFO_SOURCE` is set, `Flow(...)` / `ApiFlow(...)` will auto-resolve `node_info` when none is provided.
169
+
170
+ ```python
171
+ # api — use Flow to work with workflow.json natively
172
+ from autograph import Flow
173
+
174
+ flow = Flow("workflow.json") # uses AUTOGRAPH_COMFYUI_SERVER_URL
175
+ flow.save("workflow-out.json") # stays in workspace format
176
+
177
+ # or convert to API payload
178
+ api = flow.convert()
179
+ api.save("workflow-api.json")
180
+ ```
181
+
182
+ > **Note:** `ApiFlow("workflow.json")` also works and always converts to the API format. `Flow` keeps the workspace format and converts on demand.
183
+
184
+ ```bash
185
+ # cli
186
+ python -m autograph --input-path workflow.json --output-path workflow-api.json
187
+ ```
188
+
189
+ - More: [`docs/convert.md`](docs/convert.md), [`docs/node-info-and-env.md`](docs/node-info-and-env.md)
190
+
191
+
192
+ ## Convert `workflow` to `workflow-api` (offline)
193
+
194
+ Convert using your saved `node-info.json` (no server needed).
195
+
196
+ ```mermaid
197
+ flowchart LR
198
+ workflowJson["workflow.json"] --> wf["Flow(...)"]
199
+ objectInfo["node-info.json"] --> wf
200
+ wf --> flow["Flow"]
201
+ flow --> convert["flow.convert()"]
202
+ convert --> apiFlow["ApiFlow"]
203
+ apiFlow --> saveApi["save(workflow-api.json)"]
204
+ ```
205
+
206
+ ```python
207
+ # api — Flow-first: load, optionally edit, then convert
208
+ from autograph import Flow
209
+
210
+ flow = Flow("workflow.json", node_info="node-info.json")
211
+ flow.save("workflow-out.json") # save workspace format
212
+
213
+ api = flow.convert() # convert to API payload
214
+ api.save("workflow-api.json") # save API format
215
+ ```
216
+
217
+ ```bash
218
+ # cli
219
+ # Offline mode (saved node_info)
220
+ python -m autograph --input-path workflow.json --output-path workflow-api.json --node-info-path node-info.json
221
+
222
+ # Short form (flags)
223
+ python -m autograph -i workflow.json -o workflow-api.json -f node-info.json
224
+ ```
225
+
226
+ - More: [`docs/convert.md`](docs/convert.md)
227
+
228
+ ## Build Workflows from Scratch
229
+
230
+ Create and wire ComfyUI workflows entirely from Python — full tab completion, Pythonic dict-like views, and multiple connection syntaxes.
231
+
232
+ ```python
233
+ from autograph import Flow, NodeInfo
234
+
235
+ flow = Flow(node_info="node-info.json")
236
+
237
+ # Add nodes
238
+ ckpt = flow.add_node("CheckpointLoaderSimple")
239
+ pos = flow.add_node("CLIPTextEncode", text="a beautiful landscape")
240
+ neg = flow.add_node("CLIPTextEncode", text="ugly, blurry")
241
+ lat = flow.add_node("EmptyLatentImage", width=1024, height=1024)
242
+ ks = flow.add_node("KSampler", seed=42, steps=20, cfg=7.0)
243
+ vae = flow.add_node("VAEDecode")
244
+ save = flow.add_node("SaveImage", filename_prefix="test")
245
+
246
+ # Wire connections — all equivalent styles:
247
+ ckpt.outputs.MODEL >> ks.inputs.model # explicit push
248
+ ks.inputs.positive << pos # pull (auto-resolve output)
249
+ ckpt.outputs.CLIP >> [pos.inputs.clip, neg.inputs.clip] # fan-out
250
+ ckpt >> vae.vae # shorthand (auto-resolve)
251
+
252
+ # Inspect connections
253
+ ks.inputs # {'model': 'CheckpointLoaderSimple.MODEL', 'positive': None, ...}
254
+ ckpt.outputs # {'MODEL': 'KSampler.model', 'CLIP': '...', 'VAE': None}
255
+ print(ks.inputs.status()) # full ANSI-colored status table
256
+
257
+ # Disconnect
258
+ ks.inputs.model << None # operator
259
+ ckpt.outputs.CLIP.disconnect(pos.inputs.clip) # targeted
260
+
261
+ # Save
262
+ flow.auto_layout()
263
+ flow.save("my-workflow.json")
264
+ ```
265
+
266
+ - `node.inputs` / `node.outputs` — dict-like views: `[]`, `pop()`, `del`, `keys/values/items`
267
+ - `flow.nodes.KSampler` returns the same `NodeRef` as `flow.add_node()`
268
+ - `.status()` on any view gives a full ANSI-colored connection table
269
+
270
+ ## Load from PNG (extract embedded workflow)
271
+
272
+ ComfyUI embeds workflow metadata in PNG outputs. Extract it directly—no external dependencies needed.
273
+
274
+ ```python
275
+ # api
276
+ from autograph import Flow, ApiFlow
277
+
278
+ # From PNG file
279
+ api_flow = ApiFlow.load("ComfyUI_00001_.png") # extracts API payload
280
+ flow = Flow.load("ComfyUI_00001_.png") # extracts workspace
281
+
282
+ # From bytes (e.g., HTTP upload, database blob)
283
+ with open("output.png", "rb") as f:
284
+ api_flow = ApiFlow.load(f.read())
285
+ ```
286
+
287
+ All `.load()` methods accept: `dict`, `bytes`, `str` (JSON or path), `Path`
288
+
289
+ ## Submit + images (optional)
290
+ Submit your `ApiFlow` directly to ComfyUI and get images back
291
+ ```mermaid
292
+ flowchart LR
293
+ apiFlow["ApiFlow"] ==> submit["submit(wait=True)"]
294
+ submit ==> comfy["ComfyUI server"]
295
+ comfy --> |job handle|apiFlow
296
+ apiFlow ---> |job handle| images["fetch_images().save(...)"]
297
+ ```
298
+
299
+ ```python
300
+ # api
301
+ from autograph import ApiFlow
302
+
303
+ api = ApiFlow("workflow.json")
304
+ api.saveimage.inputs.filename_prefix='autograph'
305
+ res = api.submit(server_url="http://localhost:8188", wait=True)
306
+ images = res.fetch_images()
307
+ images.save("outputs/frame.###.png")
308
+ ```
309
+
310
+ You can also set an output default with env `AUTOGRAPH_OUTPUT_PATH` and then just provide a `filename=` template:
311
+
312
+ ```python
313
+ # api
314
+ images.save(filename="frame.{src_frame}.png") # or "frame.###.png" for zero-indexed numbering
315
+ ```
316
+
317
+ ```bash
318
+ # cli
319
+ # Prints prompt_id first, then (if saving) the written file paths. Progress logs go to stderr.
320
+ python -m autograph --submit --input-path workflow.json --server-url http://localhost:8188 \
321
+ --save-images outputs --filepattern "frame.###.png" --index-offset 1001
322
+ ```
323
+
324
+ - More: [`docs/submit-and-images.md`](docs/submit-and-images.md), [`docs/progress-events.md`](docs/progress-events.md)
325
+
326
+ ## Serverless execute (no ComfyUI HTTP server)
327
+
328
+ If you're running inside a ComfyUI environment (repo + venv), you can run workflows serverlessly:
329
+
330
+ - Details: [`docs/execute.md`](docs/execute.md)
331
+
332
+ ## Optional Functionality
333
+
334
+ - **Polymorphic loading** (dict, bytes, JSON string, file path, PNG):
335
+ - all `.load()` methods auto-detect input type: [`docs/load-vs-convert.md`](docs/load-vs-convert.md)
336
+ - extract workflows from ComfyUI PNG outputs (no dependencies)
337
+ - **OOP node access**:
338
+ - `api.KSampler.seed = 42` — attribute-style access by class_type
339
+ - `api.find(class_type="KSampler")[0].seed = 42` — search + then edit (returns NodeProxy objects)
340
+ - `api.KSampler._meta` / `.meta` — access node metadata
341
+ - `api["ksampler/seed"]` — path-style access
342
+ - `api["18:17:3/seed"] = 42` — edit nodes inside flattened subgraph exports (ComfyUI-style path IDs)
343
+ - `flow.nodes.KSampler.type` — explicit via `.nodes` for workspace flows
344
+ - `flow.nodes.find(title="NewSubgraphName")[0].path()` — find renamed subgraph instances; prints a stable path like `18:17:3`
345
+ - `flow.extra.ds.scale` — drill into nested dicts with `DictView`
346
+ - `node.properties.models.url` — single-item list-of-dicts drill via `ListView` (otherwise index first)
347
+ - **Widget-value repr**: `NodeRef`/`NodeSet` display widget values as dicts — `f.nodes.CheckpointLoaderSimple` → `{'nodes.CheckpointLoaderSimple[0]': {'ckpt_name': '...'}}`
348
+ - **Widget introspection**: `.choices()` returns valid combo options, `.tooltip()` shows help text, `.spec()` gives the raw `node_info` spec
349
+ - **Tab completion**: curated `__dir__` on `ApiFlow`, `NodeSet`, `FlowTreeNodesView`, and `WidgetValue` — only shows user-facing attrs
350
+ - **Indexed nodes**: standard Python REPL can't tab-complete `api.KSampler[0].<tab>` — assign to a variable first: `k = api.KSampler[0]` then `k.<tab>`
351
+ - **Mapping** (seeds/paths/prompts):
352
+ - typed callback mapping: [`docs/mapping.md`](docs/mapping.md)
353
+ - declarative string/path mapping: [`docs/map-strings-and-paths.md`](docs/map-strings-and-paths.md)
354
+ - cache-busting repeat runs: [`docs/force-recompute.md`](docs/force-recompute.md)
355
+ - **Filename pattern saving**:
356
+ - `ImagesResult.save("outputs/frame.###.png")`: [`docs/submit-and-images.md`](docs/submit-and-images.md)
357
+ - **Service patterns**:
358
+ - FastAPI integration: [`docs/fastapi.md`](docs/fastapi.md)
359
+ - structured errors: [`docs/error-handling.md`](docs/error-handling.md)
360
+ - **When things break**:
361
+ - troubleshooting: [`docs/troubleshooting.md`](docs/troubleshooting.md)
362
+ - deeper options: [`docs/advanced.md`](docs/advanced.md)
363
+
364
+ ## CLI Reference
365
+
366
+ | Argument | Short | Description |
367
+ |----------|-------|-------------|
368
+ | `--input-path` | `-i` | Input workflow JSON file path |
369
+ | `--output-path` | `-o` | Output API format JSON file path |
370
+ | `--server-url` | | ComfyUI server URL (or set `AUTOGRAPH_COMFYUI_SERVER_URL`) |
371
+ | `--node-info-path` | `-f` | Path to saved `node_info.json` file |
372
+ | `--download-node-info-path` | | Download `/object_info` and save to file |
373
+ | `--submit` | | Submit converted API payload to ComfyUI |
374
+ | `--no-wait` | | Submit without waiting for completion (prints `prompt_id` and exits) |
375
+ | `--no-progress` | | Disable progress output during `--submit` when waiting |
376
+ | `--save-images` | | Directory to save fetched images (requires waiting) |
377
+ | `--filepattern` | | Filename pattern used when saving images (default: `frame.###.png`) |
378
+ | `--index-offset` | | Index offset for `#` patterns (default: 0) |
379
+ | `--save-files` | | Directory to save fetched registered files (requires waiting) |
380
+ | `--output-types` | | Comma-separated registered output types when saving files (e.g. `images,files`) |
381
+
382
+ **Note**: The CLI supports submission and saving registered outputs via `--submit` (see [`docs/submit-and-images.md`](docs/submit-and-images.md) and [`docs/progress-events.md`](docs/progress-events.md)).
383
+
384
+ ## Contributing
385
+
386
+ This script is designed to be production-ready and maintainable. Key design principles:
387
+
388
+ - **Minimal Dependencies**: Uses only Python standard library
389
+ - **Cross-Platform Compatibility**: Works on Linux, Windows, and macOS
390
+ - **Robust Error Handling**: Graceful degradation and detailed error reporting
391
+ - **Exact Replication**: Matches ComfyUI's internal conversion exactly
392
+
393
+ For development setup, running tests, and code style guidelines, see [`CONTRIBUTING.md`](CONTRIBUTING.md).
394
+
395
+ ## License
396
+
397
+ [`MIT License`](LICENSE)
398
+
399
+ ## Related
400
+
401
+ - [ComfyUI](https://github.com/comfyanonymous/ComfyUI) - The main ComfyUI project
402
+ - [ComfyUI API Documentation](https://github.com/comfyanonymous/ComfyUI/wiki/API) - API format specification
403
+