Skip to content

jongmin-oh/comfyUI-api-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ComfyUI API Server

The fastest way to serve Stable Diffusion as a production API.

ComfyUI's speed and optimization. SD WebUI's familiar REST interface. Zero compromises.

Python FastAPI ComfyUI Docker License

Quick Start · API Reference · Docker Setup · Examples


Why This Exists

SD WebUI ComfyUI This Project
REST API (/sdapi/v1)
Generation Speed Slow Fast Fast
Latest Samplers & Optimizations
LoRA Chaining Limited
No Disk I/O for API calls
Headless / Server-optimized
Docker-ready

ComfyUI is fast and powerful, but has no REST API. SD WebUI has a great API, but is slow and heavy.

This project is a minimal FastAPI server built on top of ComfyUI's execution engine that exposes the sdapi/v1 interface — so every tool, script, and app built for SD WebUI just works, while running at ComfyUI speed.

All UI-related code has been removed. This is a pure server.


Features

  • SDAPI compatible — Drop-in replacement for SD WebUI's /sdapi/v1/txt2img and /sdapi/v1/img2img endpoints
  • Pure in-memory I/O — Images are passed as base64 strings; nothing is written to disk during inference
  • LoRA chaining — Apply multiple LoRAs in a single request with independent strength_model and strength_clip controls
  • 17+ samplers — Euler, DPM++ 2M Karras, DDIM, UniPC, Heun, and more — all mapped from SD WebUI names
  • CLIP skip — Full clip layer depth control
  • img2img with inpainting — Mask-based inpainting with denoising strength control
  • LRU model caching — Keep frequently used models in VRAM between requests
  • Docker + NVIDIA GPU — One command to build and run

Quick Start

Option 1 — Docker (Recommended)

git clone https://github.com/jongmin-oh/comfyUI-api-server
cd comfyui-api-server

# Place your model checkpoints and LoRAs
mkdir -p models/checkpoints models/loras
cp your_model.safetensors models/checkpoints/

# Build and run
bash refresh.sh

The server starts on http://localhost:7860.

Option 2 — Local Python

git clone https://github.com/jongmin-oh/comfyUI-api-server
cd comfyui-api-server

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

python main.py --gpu-only --cache-lru 50

API Reference

The server exposes a subset of the SD WebUI SDAPI spec. Any client library that targets SD WebUI will work out of the box.

POST /sdapi/v1/txt2img

Generate an image from a text prompt.

{
  "prompt": "a photorealistic portrait of a woman, 8k, dramatic lighting",
  "negative_prompt": "blurry, low quality, watermark",
  "width": 1024,
  "height": 1024,
  "steps": 20,
  "cfg_scale": 7.0,
  "sampler_name": "DPM++ 2M Karras",
  "seed": -1,
  "batch_size": 1,
  "override_settings": {
    "sd_model_checkpoint": "your_model.safetensors"
  },
  "loras": [
    { "name": "your_lora.safetensors", "strength_model": 0.8, "strength_clip": 0.8 }
  ]
}

Response:

{
  "images": ["<base64-encoded PNG>"],
  "parameters": { ... },
  "info": "..."
}

POST /sdapi/v1/img2img

Modify an existing image using a prompt.

{
  "init_images": ["<base64-encoded input image>"],
  "prompt": "same person, cyberpunk style, neon lighting",
  "negative_prompt": "blurry, low quality",
  "denoising_strength": 0.6,
  "width": 1024,
  "height": 1024,
  "steps": 20,
  "sampler_name": "Euler",
  "override_settings": {
    "sd_model_checkpoint": "your_model.safetensors"
  }
}

GET /sdapi/v1/sd-models

List all available checkpoint models.

[
  {
    "title": "your_model.safetensors",
    "model_name": "your_model",
    "filename": "/app/models/checkpoints/your_model.safetensors",
    "hash": "abc123",
    "sha256": "..."
  }
]

GET /sdapi/v1/samplers

List all available samplers with their aliases.

[
  { "name": "Euler", "aliases": ["euler"], "options": {} },
  { "name": "DPM++ 2M Karras", "aliases": ["dpmpp_2m_karras"], "options": {} },
  ...
]

Supported Samplers

SDAPI Name ComfyUI Sampler Scheduler
Euler euler normal
Euler a euler_ancestral normal
Heun heun normal
DPM2 dpm_2 normal
DPM2 a dpm_2_ancestral normal
DPM++ 2S a dpmpp_2s_ancestral normal
DPM++ 2M dpmpp_2m normal
DPM++ SDE dpmpp_sde normal
DPM++ 2M Karras dpmpp_2m karras
DPM++ 2M SDE Karras dpmpp_2m_sde karras
DPM++ 3M SDE Karras dpmpp_3m_sde karras
DDIM ddim normal
UniPC uni_pc normal
LMS lms normal

Docker Setup

Dockerfile Overview

Base:    nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04
Python:  3.11
Port:    7860
Command: python3 main.py --gpu-only --cache-lru 50

refresh.sh

bash refresh.sh

This script:

  1. Builds the Docker image tagged comfyui-api
  2. Stops and removes any existing container
  3. Runs a new container with:
    • NVIDIA GPU access (--runtime=nvidia)
    • Shared memory for multi-process PyTorch (--ipc=host)
    • Auto-restart on failure (--restart=always)
    • Local models/ directory mounted into the container

Manual Docker Run

docker build -t comfyui-api .

docker run -d \
  --name comfyui-api \
  --runtime=nvidia \
  --ipc=host \
  --restart=always \
  -p 7860:7860 \
  -v $(pwd)/models:/app/models \
  comfyui-api

Model Setup

Place model files in the models/ directory before starting the server:

models/
├── checkpoints/       # Main diffusion models (.safetensors, .ckpt)
│   └── your_model.safetensors
└── loras/             # LoRA models
    └── your_lora.safetensors

The server automatically detects all files in these directories at startup. No restart needed when using the override_settings.sd_model_checkpoint parameter to switch models per-request.


Examples

Python — txt2img

import requests, base64, json
from PIL import Image
from io import BytesIO

response = requests.post("http://localhost:7860/sdapi/v1/txt2img", json={
    "prompt": "a beautiful landscape, golden hour, 8k",
    "negative_prompt": "blurry, low quality",
    "width": 1024,
    "height": 1024,
    "steps": 20,
    "cfg_scale": 7.0,
    "sampler_name": "DPM++ 2M Karras",
    "seed": 42,
    "override_settings": {
        "sd_model_checkpoint": "your_model.safetensors"
    }
})

result = response.json()
image = Image.open(BytesIO(base64.b64decode(result["images"][0])))
image.save("output.png")

Python — img2img

import requests, base64, json
from PIL import Image
from io import BytesIO

# Load and encode the input image
with open("input.png", "rb") as f:
    input_b64 = base64.b64encode(f.read()).decode("utf-8")

response = requests.post("http://localhost:7860/sdapi/v1/img2img", json={
    "init_images": [input_b64],
    "prompt": "same scene, winter, snow",
    "denoising_strength": 0.6,
    "width": 1024,
    "height": 1024,
    "steps": 20,
    "sampler_name": "Euler",
    "override_settings": {
        "sd_model_checkpoint": "your_model.safetensors"
    }
})

result = response.json()
image = Image.open(BytesIO(base64.b64decode(result["images"][0])))
image.save("output.png")

cURL — txt2img

curl -s -X POST http://localhost:7860/sdapi/v1/txt2img \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "a cat sitting on a windowsill",
    "steps": 20,
    "width": 512,
    "height": 512,
    "sampler_name": "Euler",
    "override_settings": {"sd_model_checkpoint": "your_model.safetensors"}
  }' | python3 -c "
import sys, json, base64
data = json.load(sys.stdin)
open('output.png', 'wb').write(base64.b64decode(data['images'][0]))
print('Saved output.png')
"

Architecture

HTTP Request
    │
    ▼
FastAPI Routes (/sdapi/routes.py)
    │  Parse request → Pydantic model validation
    │
    ▼
Workflow Builder (/sdapi/workflow_builder.py)
    │  Convert SDAPI params → ComfyUI node graph
    │  CheckpointLoader → LoRALoader(s) → CLIPEncode → KSampler → VAEDecode
    │
    ▼
SDAPI Executor (/sdapi/executor.py)
    │  Submit workflow to PromptQueue
    │  Async wait for completion (timeout: 300s)
    │
    ▼
ComfyUI Execution Engine (execution.py)
    │  Node-by-node graph execution
    │  GPU inference via PyTorch
    │  LRU model caching
    │
    ▼
MemoryImage Node (nodes.py)
    │  Tensor → PIL → BytesIO → base64
    │  No disk write
    │
    ▼
Serializer (/sdapi/serializer.py)
    │  History entry → SDAPI response format
    │
    ▼
HTTP Response { "images": ["<base64>"], ... }

Configuration

CLI Arguments

python main.py [options]

  --gpu-only              Use GPU only (no CPU fallback)
  --cache-lru N           LRU cache size for models in VRAM (default: 0)
  --cache-none            Disable model caching entirely
  --cache-classic         Use classic caching strategy
  --cache-ram-pressure    Evict models under RAM pressure
  --listen HOST           Bind address (default: 127.0.0.1)
  --port PORT             Port (default: 7860)
  --deterministic         Enable deterministic CUDA operations

Extra Model Paths

To load models from external directories, create extra_model_paths.yaml:

a1111:
  base_path: /path/to/stable-diffusion-webui/
  checkpoints: models/Stable-diffusion
  loras: models/Lora
  vae: models/VAE

Requirements

  • Python 3.10+
  • NVIDIA GPU with CUDA 12.4 support
  • 8GB+ VRAM (16GB+ recommended for SDXL)
  • Docker + NVIDIA Container Toolkit (for Docker deployment)

Acknowledgements

This project is built on top of ComfyUI by @comfyanonymous. The SDAPI interface is modeled after AUTOMATIC1111/stable-diffusion-webui.


License

GPL-3.0. See LICENSE.

Releases

No releases published

Packages

 
 
 

Contributors

Languages