Skip to main content

Python SDK for running ComfyUI workflows on RunPod — serverless endpoints and persistent pods.

Project description

Mirror Fit SDK

A Python SDK for running ComfyUI workflows on RunPod — supports both serverless endpoints and persistent pod instances through a single unified client.

No need to match hardcoded filenames in your workflow JSON. Pass any local image paths and the SDK auto-patches the LoadImage nodes in order.

Installation

pip install mirror-fit-sdk

Quick Start

from mirror_fit import MirrorFitClient

client = MirrorFitClient()

# Serverless endpoint
sl  = client.serverless(api_key="YOUR_KEY", endpoint_id="YOUR_ENDPOINT_ID")

# Persistent pod
pod = client.pod(pod_id="YOUR_POD_ID", api_key="YOUR_KEY")

Serverless Usage

Use this when your ComfyUI is deployed as a RunPod serverless endpoint.

Initialize

from mirror_fit import MirrorFitClient

client = MirrorFitClient()
sl = client.serverless(
    api_key="YOUR_RUNPOD_API_KEY",
    endpoint_id="YOUR_RUNPOD_ENDPOINT_ID",
)

Check Health

health = sl.get_health()
print(health)
# {"workers": {"idle": 2, "running": 0}, "jobs": {...}}

Run Synchronously

Blocks until the generation completes and returns results.

result = sl.run_sync(
    workflow="workflow_api.json",   # path or pre-loaded dict
    images=["photo.jpg", "bg.png"], # any filenames — SDK patches the workflow
)
print(result["output"]["images"])   # list of base64 strings

Run Asynchronously

Submit a job and collect the result later — ideal for long workflows.

# Submit and return immediately
job_id = sl.run_async(workflow="workflow_api.json", images=["photo.jpg"])

# Check status without blocking
status = sl.get_status(job_id)
# {"id": "...", "status": "IN_PROGRESS"}

# Block until done and get result
result = sl.get_result(job_id)
print(result["output"]["images"])

Cancel a Job

sl.cancel(job_id)

Clear the Queue

sl.purge_queue()

Pod Usage

Use this when your ComfyUI is running on a persistent RunPod pod (always-on GPU).

Initialize

from mirror_fit import MirrorFitClient

client = MirrorFitClient()
pod = client.pod(
    pod_id="YOUR_POD_ID",          # "abc123xyz" — -8188 suffix handled automatically
    api_key="YOUR_RUNPOD_API_KEY", # omit if pod proxy port is public
)

Check Health

health = pod.get_health()
# {"status": "HEALTHY", "message": "ComfyUI Server is active and warming VRAM."}

List Available Models

Instantly see what checkpoints, VAEs, and LoRAs are installed on the pod — useful for debugging missing model errors.

models = pod.get_models()
print(models["checkpoints"])  # ["flux-2-klein-9b-fp8.safetensors", ...]
print(models["vaes"])         # ["flux2-vae.safetensors"]
print(models["loras"])        # [...]

Check the Queue

q = pod.get_queue()
print(f"Running: {len(q['queue_running'])}, Pending: {len(q['queue_pending'])}")

Run Synchronously

result = pod.run_sync(
    workflow="workflow_api.json",
    images=["photo.jpg", "bg.png"],  # any filenames — SDK patches the workflow
    timeout_seconds=300,             # default 240
)
print(result["output"]["images"])    # list of base64 strings

Run Asynchronously

# Submit without waiting
prompt_id = pod.run_async(workflow="workflow_api.json", images=["photo.jpg"])

# Collect when ready
result = pod.get_result(prompt_id, timeout_seconds=300)
print(result["output"]["images"])

Fetch History

# Full history of recent executions
history = pod.get_history()

# History for a specific prompt
history = pod.get_history(prompt_id="some-prompt-id")

Upload an Image

Pre-upload an image independently of running a workflow.

pod.upload_image("photos/portrait.jpg")
pod.upload_image("photos/bg.png", upload_name="background.png")

Interrupt a Running Generation

pod.interrupt()

Image Handling

Both clients accept images as a list or dict. The SDK automatically patches the workflow's LoadImage nodes in order — you never have to match filenames hardcoded inside the JSON.

# List — positional: 1st image → 1st LoadImage node, 2nd → 2nd, etc.
images=["input/photo.jpg", "input/bg.png"]

# Dict — explicit upload name → local path (same positional patching applies)
images={"portrait.jpg": "input/photo.jpg", "background.png": "input/bg.png"}

API Reference

MirrorFitClient

Stateless factory — holds no credentials.

Method Returns Description
.serverless(api_key, endpoint_id) ServerlessClient Client for a RunPod serverless endpoint
.pod(pod_id, api_key=None) PodClient Client for a persistent RunPod pod

ServerlessClient

Obtained via client.serverless(api_key, endpoint_id).

Method Description
get_health() Endpoint health and worker counts
run_sync(workflow, images, timeout=300) Execute workflow, block until done
run_async(workflow, images)job_id Submit job, return immediately
get_status(job_id) Check job status without fetching output
get_result(job_id) Poll until done, return full result
cancel(job_id) Cancel a queued or running job
purge_queue() Remove all pending jobs from the endpoint

run_sync / run_async parameters

Parameter Type Required Description
workflow str | dict Path to workflow_api.json or pre-loaded dict
images list[str] | dict[str,str] Local paths (list) or {upload_name: local_path}

PodClient

Obtained via client.pod(pod_id, api_key=None).

Method Description
get_health() Check if ComfyUI server is alive
get_queue() View running and pending prompts
get_history(prompt_id=None) Retrieve past execution history
get_models() List installed checkpoints, VAEs, LoRAs, CLIPs, UNETs
upload_image(filepath, upload_name=None) Upload an image to the pod's input folder
interrupt() Stop the currently running generation
run_sync(workflow, images, timeout_seconds=240) Execute workflow, block until done
run_async(workflow, images)prompt_id Queue prompt, return immediately
get_result(prompt_id, timeout_seconds=240) Poll until done, return full result

run_sync / run_async parameters

Parameter Type Required Description
workflow str | dict Path to workflow_api.json or pre-loaded dict
images list[str] | dict[str,str] Local paths (list) or {upload_name: local_path}
timeout_seconds int Max wait before TimeoutError (default 240)

Response Format

All run_sync and get_result calls return the same shape:

{
  "id": "prompt-uuid",
  "status": "COMPLETED",
  "delayTime": 1200,
  "executionTime": 8500,
  "output": {
    "message": "Generation completed successfully.",
    "images": ["<base64>", "<base64>"]
  }
}

Saving Output Images

import base64, os

def save_images(result, output_dir="output"):
    os.makedirs(output_dir, exist_ok=True)
    for i, b64 in enumerate(result["output"]["images"]):
        path = os.path.join(output_dir, f"output_{i+1}.png")
        with open(path, "wb") as f:
            f.write(base64.b64decode(b64))
        print(f"Saved: {path}")

result = pod.run_sync(workflow="workflow_api.json", images=["photo.jpg"])
save_images(result)

Error Handling

import requests

try:
    result = pod.run_sync(workflow="workflow_api.json", images=["photo.jpg"])
except TimeoutError:
    print("Workflow timed out — try increasing timeout_seconds")
except requests.HTTPError as e:
    print(f"HTTP {e.response.status_code}: {e}")   # includes ComfyUI error body for 500s
except RuntimeError as e:
    print(f"Job failed: {e}")                       # raised by get_result on FAILED jobs
except Exception as e:
    print(f"Unexpected error: {e}")

Requirements

  • Python 3.9+
  • requests >= 2.32.0
  • Active RunPod account
  • A deployed ComfyUI serverless endpoint and/or a running ComfyUI pod

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mirror_fit_sdk-0.2.2.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mirror_fit_sdk-0.2.2-py3-none-any.whl (16.3 kB view details)

Uploaded Python 3

File details

Details for the file mirror_fit_sdk-0.2.2.tar.gz.

File metadata

  • Download URL: mirror_fit_sdk-0.2.2.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mirror_fit_sdk-0.2.2.tar.gz
Algorithm Hash digest
SHA256 2ede066077addbe35f0e6ec914d2c4c578513fa73d079113bf63adedf4bacb40
MD5 bfeb803abe2644c933bbad09397a6fe6
BLAKE2b-256 3cbc6f8a667b08deb5b520b74af1d049803da4f8ceb1bd0fadab1ac84fc8714e

See more details on using hashes here.

File details

Details for the file mirror_fit_sdk-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: mirror_fit_sdk-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 16.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mirror_fit_sdk-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c9f0419c0fd5ad915cd1516a6c4121197bf9fcb313fb40c0c7ea41c8c45fd1f0
MD5 f10ad171a9b6b43e6a403806b02eef8a
BLAKE2b-256 b2431e777cb0b239fccef5d4f0dc4dcea1a356b813b81416517310f4adfdd9e2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page