Spaces:
Sleeping
Sleeping
| """ | |
| Generation Request Model | |
| ======================== | |
| Data model for image generation requests. | |
| Provides type-safe structure for all generation parameters. | |
| """ | |
| from dataclasses import dataclass, field | |
| from typing import List, Optional | |
| from PIL import Image | |
| class GenerationRequest: | |
| """ | |
| Represents a request for image generation. | |
| This is the standard interface for all generation requests, | |
| regardless of backend or generation type. | |
| Attributes: | |
| prompt: Text prompt describing desired image | |
| backend: Backend to use ("Gemini API (Cloud)" or "OmniGen2 (Local)") | |
| aspect_ratio: Aspect ratio (e.g. "16:9", "3:4") | |
| temperature: Temperature/creativity parameter (0.0-1.0) | |
| input_images: Optional list of input images for image-to-image | |
| is_character_sheet: Mark input images as character sheets | |
| metadata: Additional metadata for tracking | |
| """ | |
| # Required fields | |
| prompt: str | |
| backend: str | |
| aspect_ratio: str | |
| temperature: float | |
| # Optional fields | |
| input_images: Optional[List[Image.Image]] = None | |
| is_character_sheet: List[bool] = field(default_factory=list) | |
| metadata: dict = field(default_factory=dict) | |
| negative_prompt: Optional[str] = None | |
| seed: Optional[int] = None | |
| def __post_init__(self): | |
| """Validate and normalize data after initialization.""" | |
| # Ensure prompt is string | |
| if not isinstance(self.prompt, str): | |
| raise TypeError("prompt must be a string") | |
| # Strip whitespace from prompt | |
| self.prompt = self.prompt.strip() | |
| # Ensure temperature is numeric | |
| if not isinstance(self.temperature, (int, float)): | |
| raise TypeError("temperature must be numeric") | |
| # Convert temperature to float | |
| self.temperature = float(self.temperature) | |
| # Normalize input_images (convert None to empty list) | |
| if self.input_images is None: | |
| self.input_images = [] | |
| # Ensure is_character_sheet matches input_images length | |
| if len(self.is_character_sheet) < len(self.input_images): | |
| # Pad with False | |
| self.is_character_sheet.extend( | |
| [False] * (len(self.input_images) - len(self.is_character_sheet)) | |
| ) | |
| def has_input_images(self) -> bool: | |
| """Check if request has input images.""" | |
| return self.input_images is not None and len(self.input_images) > 0 | |
| def image_count(self) -> int: | |
| """Get number of input images.""" | |
| return len(self.input_images) if self.input_images else 0 | |
| def is_text_to_image(self) -> bool: | |
| """Check if this is a text-to-image request (no input images).""" | |
| return not self.has_input_images | |
| def is_image_to_image(self) -> bool: | |
| """Check if this is an image-to-image request (has input images).""" | |
| return self.has_input_images | |
| def to_dict(self) -> dict: | |
| """ | |
| Convert request to dictionary (for metadata/logging). | |
| Note: Images are not included in dict (only count). | |
| Returns: | |
| Dictionary representation | |
| """ | |
| return { | |
| "prompt": self.prompt, | |
| "backend": self.backend, | |
| "aspect_ratio": self.aspect_ratio, | |
| "temperature": self.temperature, | |
| "input_image_count": self.image_count, | |
| "is_character_sheet": self.is_character_sheet, | |
| "negative_prompt": self.negative_prompt, | |
| "seed": self.seed, | |
| "metadata": self.metadata | |
| } | |
| def __repr__(self) -> str: | |
| """String representation for debugging.""" | |
| return ( | |
| f"GenerationRequest(" | |
| f"prompt='{self.prompt[:50]}...', " | |
| f"backend='{self.backend}', " | |
| f"aspect_ratio='{self.aspect_ratio}', " | |
| f"temperature={self.temperature}, " | |
| f"input_images={self.image_count})" | |
| ) | |