Spaces:
Sleeping
Sleeping
| """ | |
| Application Settings and Configuration | |
| ======================================= | |
| Centralized configuration management for Nano Banana Streamlit. | |
| All environment variables, paths, and constants defined here. | |
| """ | |
| import os | |
| from pathlib import Path | |
| from typing import Optional | |
| class Settings: | |
| """ | |
| Application-wide settings and configuration. | |
| This class uses class methods and properties to provide | |
| a simple interface for accessing configuration values. | |
| """ | |
| # ========================================================================= | |
| # PROJECT PATHS | |
| # ========================================================================= | |
| # Root directory of the project | |
| PROJECT_ROOT = Path(__file__).parent.parent | |
| # Output directory for generated images | |
| OUTPUT_DIR = PROJECT_ROOT / "outputs" | |
| # Ensure output directory exists | |
| OUTPUT_DIR.mkdir(exist_ok=True) | |
| # Subdirectories for different generation types | |
| CHARACTER_SHEETS_DIR = OUTPUT_DIR / "character_sheets" | |
| WARDROBE_CHANGES_DIR = OUTPUT_DIR / "wardrobe_changes" | |
| COMPOSITIONS_DIR = OUTPUT_DIR / "compositions" | |
| STANDARD_DIR = OUTPUT_DIR / "standard" | |
| # Create all subdirectories | |
| for directory in [CHARACTER_SHEETS_DIR, WARDROBE_CHANGES_DIR, | |
| COMPOSITIONS_DIR, STANDARD_DIR]: | |
| directory.mkdir(exist_ok=True) | |
| # Log file | |
| LOG_FILE = OUTPUT_DIR / "generation.log" | |
| # ========================================================================= | |
| # API KEYS AND CREDENTIALS | |
| # ========================================================================= | |
| def get_gemini_api_key(cls) -> Optional[str]: | |
| """ | |
| Get Gemini API key from environment variable. | |
| Returns: | |
| API key string if set, None otherwise | |
| """ | |
| return os.environ.get("GEMINI_API_KEY") | |
| # ========================================================================= | |
| # BACKEND CONFIGURATION | |
| # ========================================================================= | |
| # OmniGen2 server URL | |
| OMNIGEN2_BASE_URL = "http://127.0.0.1:9002" | |
| # ComfyUI server URL | |
| COMFYUI_BASE_URL = "http://127.0.0.1:8188" | |
| # Backend timeout (seconds) | |
| # Set to None for local backends (ComfyUI) - no timeout needed, monitor logs instead | |
| # For network/API backends (Gemini), keep a reasonable timeout | |
| BACKEND_TIMEOUT = None # No timeout for local models (was 600s / 10 min) | |
| # ========================================================================= | |
| # GENERATION PARAMETERS | |
| # ========================================================================= | |
| # Available aspect ratios | |
| ASPECT_RATIOS = { | |
| "1:1 (1024x1024)": "1:1", | |
| "16:9 (1344x768)": "16:9", | |
| "9:16 (768x1344)": "9:16", | |
| "3:2 (1248x832)": "3:2", | |
| "2:3 (832x1248)": "2:3", | |
| "3:4 (864x1184)": "3:4", # Character portraits (Gemini actual output) | |
| "4:3 (1344x1008)": "4:3", | |
| "4:5 (1024x1280)": "4:5", | |
| "5:4 (1280x1024)": "5:4", | |
| "21:9 (1536x640)": "21:9", | |
| } | |
| # Default generation parameters | |
| DEFAULT_ASPECT_RATIO = "16:9 (1344x768)" | |
| DEFAULT_TEMPERATURE = 0.4 | |
| MIN_TEMPERATURE = 0.0 | |
| MAX_TEMPERATURE = 1.0 | |
| TEMPERATURE_STEP = 0.05 | |
| # ========================================================================= | |
| # CHARACTER FORGE SETTINGS | |
| # ========================================================================= | |
| # Aspect ratios for character sheet views | |
| PORTRAIT_ASPECT_RATIO = "3:4" # For face portraits (864x1184) | |
| BODY_ASPECT_RATIO = "9:16" # For full body shots (768x1344) | |
| # Generation temperatures for each stage | |
| PORTRAIT_TEMPERATURE = 0.35 # Lower for consistency | |
| BODY_TEMPERATURE = 0.5 # Slightly higher for variety | |
| # Default negative prompts for ComfyUI qwen workflow | |
| # These help steer generation away from common errors | |
| DEFAULT_NEGATIVE_PROMPTS = { | |
| "stage_0a": "blurry, low quality, distorted, deformed, disfigured, bad anatomy, extra limbs, missing limbs, multiple people", | |
| "stage_0b": "different person, wrong face, altered features, different hair color, different eye color, low quality, blurry", | |
| "stage_1": "side view, profile, back view, different person, different face, altered facial features, different clothing, wrong outfit, blurry, low quality", | |
| "stage_2": "front view, facing camera, back view, three-quarter view, different person, different face, altered features, different clothing, wrong outfit, blurry, low quality", | |
| "stage_3": "front view, facing camera, back view, rear view, different person, different face, different body, altered proportions, different clothing, costume change, nude, undressed, blurry, low quality, cut off, cropped, incomplete body", | |
| "stage_4": "front view, facing camera, side view, profile view, face visible, different person, different body, different clothing, costume change, nude, undressed, blurry, low quality, cut off, cropped, incomplete body" | |
| } | |
| # Composition settings | |
| CHARACTER_SHEET_SPACING = 20 # Pixels between rows | |
| CHARACTER_SHEET_BACKGROUND = "#2C2C2C" # Dark gray | |
| # Retry logic | |
| MAX_RETRIES = 3 | |
| RETRY_BASE_DELAY = 2 # Seconds (exponential backoff) | |
| RATE_LIMIT_DELAY_MIN = 2.0 # Seconds | |
| RATE_LIMIT_DELAY_MAX = 3.0 # Seconds | |
| # ========================================================================= | |
| # LOGGING CONFIGURATION | |
| # ========================================================================= | |
| LOG_LEVEL = "INFO" | |
| LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" | |
| LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S" | |
| # Rotating file handler settings | |
| LOG_MAX_BYTES = 10 * 1024 * 1024 # 10 MB | |
| LOG_BACKUP_COUNT = 5 # Keep 5 backup files | |
| # ========================================================================= | |
| # UI CONFIGURATION | |
| # ========================================================================= | |
| # Maximum image upload size (MB) | |
| MAX_IMAGE_UPLOAD_SIZE = 20 # MB | |
| # Image display size | |
| PREVIEW_IMAGE_WIDTH = 512 # Pixels | |
| # History display | |
| MAX_HISTORY_ITEMS = 20 | |
| # ========================================================================= | |
| # COMPOSITION ASSISTANT SETTINGS | |
| # ========================================================================= | |
| # Image type options | |
| IMAGE_TYPES = [ | |
| "Subject/Character", | |
| "Background/Environment", | |
| "Style Reference", | |
| "Product", | |
| "Texture", | |
| "Not Used" | |
| ] | |
| # Shot type options | |
| SHOT_TYPES = [ | |
| "close-up shot", | |
| "medium shot", | |
| "full body shot", | |
| "wide shot", | |
| "extreme close-up", | |
| "establishing shot" | |
| ] | |
| # Camera angle options | |
| CAMERA_ANGLES = [ | |
| "eye-level perspective", | |
| "low-angle perspective", | |
| "high-angle perspective", | |
| "bird's-eye view", | |
| "Dutch angle (tilted)", | |
| "over-the-shoulder" | |
| ] | |
| # Lighting options | |
| LIGHTING_OPTIONS = [ | |
| "Auto (match images)", | |
| "natural daylight", | |
| "soft studio lighting", | |
| "dramatic side lighting", | |
| "golden hour", | |
| "blue hour", | |
| "moody low-key", | |
| "high-key bright", | |
| "rim lighting" | |
| ] | |
| # ========================================================================= | |
| # BACKEND TYPE ENUMERATION | |
| # ========================================================================= | |
| BACKEND_GEMINI = "Gemini API (Cloud)" | |
| BACKEND_OMNIGEN2 = "OmniGen2 (Local)" | |
| BACKEND_COMFYUI = "ComfyUI (Local)" | |
| BACKEND_FLUX_KREA = "FLUX Krea (Local)" # For initial portrait generation | |
| BACKEND_FLUX_KONTEXT = "FLUX Kontext (Local)" # For perspective transformations | |
| AVAILABLE_BACKENDS = [ | |
| BACKEND_GEMINI, | |
| BACKEND_OMNIGEN2, | |
| BACKEND_COMFYUI, | |
| BACKEND_FLUX_KREA, | |
| BACKEND_FLUX_KONTEXT | |
| ] | |
| # ========================================================================= | |
| # HELPER METHODS | |
| # ========================================================================= | |
| def get_aspect_ratio_value(cls, display_name: str) -> str: | |
| """ | |
| Convert display name to aspect ratio value. | |
| Args: | |
| display_name: Display name like "16:9 (1344x768)" | |
| Returns: | |
| Aspect ratio value like "16:9" | |
| """ | |
| return cls.ASPECT_RATIOS.get(display_name, "1:1") | |
| def is_gemini_configured(cls) -> bool: | |
| """Check if Gemini API is configured (API key set).""" | |
| return cls.get_gemini_api_key() is not None | |
| def validate_temperature(cls, temperature: float) -> float: | |
| """ | |
| Validate and clamp temperature to valid range. | |
| Args: | |
| temperature: Temperature value to validate | |
| Returns: | |
| Validated temperature within [MIN_TEMPERATURE, MAX_TEMPERATURE] | |
| """ | |
| return max(cls.MIN_TEMPERATURE, min(cls.MAX_TEMPERATURE, temperature)) | |
| # Make settings instance available for import | |
| settings = Settings() | |