"""Base backend interface for image generation."""
from abc import ABC, abstractmethod
from typing import Optional
from pathlib import Path
class BaseBackend(ABC):
"""Abstract base class for generation backends."""
@abstractmethod
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 an image from a text prompt.
Args:
prompt: Text description of the image to generate
negative_prompt: Things to avoid in the generation
width: Image width in pixels
height: Image height in pixels
seed: Random seed for reproducibility
steps: Number of diffusion steps
cfg_scale: Classifier-free guidance scale
**kwargs: Additional backend-specific parameters
Returns:
PNG image data as bytes
"""
pass
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:
"""Generate an image using img2img from a reference image.
Args:
reference_image: Reference image as PNG bytes
prompt: Text description for the variation
negative_prompt: Things to avoid
denoise: How much to change (0.0=identical, 1.0=completely new)
seed: Random seed for reproducibility
steps: Number of diffusion steps
cfg_scale: Classifier-free guidance scale
**kwargs: Additional backend-specific parameters
Returns:
PNG image data as bytes
"""
raise NotImplementedError("This backend does not support img2img")
async def generate_with_controlnet(
self,
prompt: str,
control_image: bytes,
controlnet_model: str = "diffusers_xl_depth_full.safetensors",
control_strength: float = 0.8,
negative_prompt: str = "",
width: int = 1024,
height: int = 1024,
seed: Optional[int] = None,
steps: int = 30,
cfg_scale: float = 6.0,
**kwargs
) -> bytes:
"""Generate an image with ControlNet guidance.
Args:
prompt: Text description
control_image: Control image (depth map, canny edges, etc.) as PNG bytes
controlnet_model: ControlNet model to use
control_strength: How strongly to follow control (0.0-1.0)
negative_prompt: Things to avoid
width: Output width
height: Output height
seed: Random seed
steps: Generation steps
cfg_scale: CFG scale
**kwargs: Additional backend-specific parameters
Returns:
PNG image data as bytes
"""
raise NotImplementedError("This backend does not support ControlNet")
@abstractmethod
async def health_check(self) -> bool:
"""Check if the backend is available and healthy."""
pass
@abstractmethod
def get_name(self) -> str:
"""Get the backend name."""
pass