A Python client library for interacting with ComfyUI API. This library provides a convenient wrapper to queue workflows, upload images/masks, and retrieve generated results (images, videos, audio, etc.) programmatically.
- Workflow Management: Queue workflows easily and wait for results.
- File Management: Upload input images and masks directly to ComfyUI.
- Generic Output Handling: Automatically handles various output types (Images, Videos/GIFs, Audio).
- Execution Control: Interrupt running tasks, check queue status, and view history.
- Node Info: Retrieve definitions for ComfyUI nodes.
pip install comfyui_xyTo use this API, you need the workflow in API Format, which is different from the standard JSON saved by ComfyUI.
-
Enable Dev Mode Options:
- In ComfyUI web interface, click the Settings (gear icon) in the menu.
- Check the option "Enable Dev mode Options".
-
Save as API Format:
- Once Dev Mode is enabled, you will see a new button in the menu: "Save (API Format)".
- Click this button to save your workflow as a JSON file (e.g.,
workflow_api.json). - Use this JSON file with the
ComfyUiClient.
import json
from comfyui_xy import ComfyUiClient
# 1. Initialize Client
client = ComfyUiClient(url="http://127.0.0.1:8188")
# 2. Load Workflow
# You should export the workflow in "API Format" from ComfyUI
with open("workflow_api.json", "r", encoding="utf-8") as f:
workflow = json.load(f)
# 3. Modify Parameters (Optional)
# e.g., Change the seed in KSampler (Node ID "3")
import random
workflow["3"]["inputs"]["seed"] = random.randint(1, 1000000000)
# 4. Run Workflow
print("Queueing workflow...")
responses = client.process_workflow(workflow)
# 5. Handle Unified Responses
for i, response in enumerate(responses):
if response.is_file:
print(f"Received file: {response.filename} ({response.file_type})")
response.save(f"output_{i}_{response.filename}")
if response.file_type == "image":
response.show()
elif response.is_text:
print(f"Received text from node {response.node_id}: {response.text}")from comfyui_xy import ComfyUiClient
# Default local server (http://127.0.0.1:8188)
client = ComfyUiClient()
# Specify URL
client = ComfyUiClient(url="http://127.0.0.1:8188")
# Remote server with HTTPS
client = ComfyUiClient(url="https://my-comfyui-server.com:8188")
# Recommended for production scripts: explicit request timeout and strict errors
client = ComfyUiClient(timeout=30, execution_timeout=300, raise_on_error=True)You can upload images or masks before running a workflow. These files are saved in the input directory of ComfyUI.
# Upload an image
# Returns the filename used by ComfyUI (useful for setting node inputs)
image_name = client.upload_image("path/to/my_image.png")
# Upload a mask
mask_name = client.upload_mask("path/to/my_mask.png")
# Example: Set the uploaded image in a LoadImage node (e.g., Node ID "10")
workflow["10"]["inputs"]["image"] = image_nameThe process_workflow method is a high-level helper that:
- Queues the prompt.
- Waits for execution to finish.
- Returns unified response objects for downloaded files and discovered text outputs.
responses = client.process_workflow(workflow)Return Value:
It returns a list of ComfyResponse objects. Each response has output_type
set to either "file" or "text".
If your workflow produces text instead of files, return the raw ComfyUI
outputs data and extract the strings directly:
outputs = client.process_workflow(workflow, return_raw=True)
texts = client.extract_text_outputs(outputs)
print(outputs)
print(texts)If you want explicit response objects from raw outputs, use:
file_responses = client.extract_file_responses(outputs)
text_responses = client.extract_text_responses(outputs)
responses = client.extract_outputs(outputs)If you want failures to be explicit instead of silently returning None / {} / [],
initialize the client with raise_on_error=True. Request failures raise
ComfyUiError, ComfyUiHttpError, or ComfyUiTimeoutError.
The ComfyResponse object wraps the raw data returned by ComfyUI.
-
Attributes:
output_type:"file"or"text".data: Raw bytes of the file for file responses.text: Extracted text for text responses.filename: Original filename on server for file responses.node_id: Source node ID in ComfyUI outputs.output_name: Output field name such asimagesortext.file_type: Type of file (e.g.,'image','video','audio','text').image: APIL.Imageobject (if the response is a valid image file).
-
Methods:
save(path=None): Save file bytes or text content to disk.show(): Opens the image in the default viewer (only for images).
Interrupt Execution:
client.interrupt()Get System Status:
# Get Queue Status (Pending/Running tasks)
queue_info = client.get_queue()
# Get Full History
history = client.get_history_all()
# Get Node Information
node_info = client.get_object_info("KSampler")You can use AsyncComfyUiClient for asynchronous operations using aiohttp.
import asyncio
from comfyui_xy import AsyncComfyUiClient
async def main():
async with AsyncComfyUiClient(url="http://127.0.0.1:8188") as client:
# Most methods are awaitable
results = await client.process_workflow(workflow)
if __name__ == "__main__":
asyncio.run(main())Check the examples/ directory for more complete scripts:
basic_workflow.py: Simple Text-to-Image generation.image_to_image.py: Uploading an image and processing it.advanced_control.py: Inspecting queue and system info.
- Added unified
ComfyResponseoutputs.process_workflow()now returns both file and text responses by default. - Kept
return_raw=Truesupport for callers that need the original ComfyUIoutputsstructure. - Added
extract_file_responses(),extract_text_responses(),extract_outputs(), andextract_text_outputs()helpers for explicit post-processing. - Added request timeout, workflow execution timeout, and strict error mode via
raise_on_error=True. - Added
ComfyUiError,ComfyUiHttpError, andComfyUiTimeoutError. - Added sync and async test coverage for raw outputs, unified responses, HTTP errors, and timeouts.
Compatibility note:
- Older code that assumed every item returned by
process_workflow()was a file should now checkresponse.is_filebefore calling file-specific logic.
MIT