"""Mock backend for testing without ComfyUI."""
import asyncio
import random
from typing import Optional
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from .base import BaseBackend
class MockBackend(BaseBackend):
"""Mock backend that generates placeholder images for testing."""
def __init__(self):
self.name = "mock"
async def generate_image(
self,
prompt: str,
negative_prompt: str = "",
width: int = 512,
height: int = 512,
seed: Optional[int] = None,
steps: int = 20,
cfg_scale: float = 7.0,
**kwargs
) -> bytes:
"""Generate a placeholder image with the prompt text."""
await asyncio.sleep(0.1) # Simulate processing time
if seed is None:
seed = random.randint(0, 2**32 - 1)
random.seed(seed)
# Create a colorful placeholder image
bg_color = (
random.randint(50, 200),
random.randint(50, 200),
random.randint(50, 200),
255
)
img = Image.new("RGBA", (width, height), bg_color)
draw = ImageDraw.Draw(img)
# Draw a border
border_color = (255, 255, 255, 200)
draw.rectangle([2, 2, width-3, height-3], outline=border_color, width=2)
# Draw grid pattern
grid_color = (255, 255, 255, 50)
for x in range(0, width, 32):
draw.line([(x, 0), (x, height)], fill=grid_color)
for y in range(0, height, 32):
draw.line([(0, y), (width, y)], fill=grid_color)
# Draw center crosshair
center_x, center_y = width // 2, height // 2
draw.line([(center_x - 20, center_y), (center_x + 20, center_y)], fill=(255, 255, 255, 150), width=2)
draw.line([(center_x, center_y - 20), (center_x, center_y + 20)], fill=(255, 255, 255, 150), width=2)
# Add text with prompt (truncated)
text = f"[MOCK]\n{prompt[:50]}..."
try:
font = ImageFont.load_default()
except:
font = None
# Draw text background
text_bbox = draw.textbbox((10, 10), text, font=font)
draw.rectangle([text_bbox[0]-5, text_bbox[1]-5, text_bbox[2]+5, text_bbox[3]+5],
fill=(0, 0, 0, 150))
draw.text((10, 10), text, fill=(255, 255, 255, 255), font=font)
# Add size info at bottom
size_text = f"{width}x{height} seed:{seed}"
draw.text((10, height - 25), size_text, fill=(255, 255, 255, 200), font=font)
# Convert to bytes
buffer = BytesIO()
img.save(buffer, format="PNG")
return buffer.getvalue()
async def generate_img2img(
self,
reference_image: bytes,
prompt: str,
negative_prompt: str = "",
denoise: float = 0.35,
seed: Optional[int] = None,
steps: int = 25,
cfg_scale: float = 6.0,
**kwargs
) -> bytes:
raise NotImplementedError("MockBackend does not support img2img. Set BACKEND_TYPE=comfyui and ensure ComfyUI is running.")
async def health_check(self) -> bool:
"""Mock backend is always healthy."""
return True
def get_name(self) -> str:
return self.name