Spaces:
Sleeping
Sleeping
| """Backend logic for DALL·E AI Image Generator.""" | |
| from __future__ import annotations | |
| import base64 | |
| import logging | |
| import os | |
| import time | |
| from datetime import datetime | |
| from io import BytesIO | |
| from pathlib import Path | |
| from typing import List, Tuple | |
| from dotenv import load_dotenv | |
| from openai import OpenAI | |
| from PIL import Image | |
| # ------------------------------------------------------------------- | |
| # Load Environment Variables | |
| # ------------------------------------------------------------------- | |
| load_dotenv() | |
| # ------------------------------------------------------------------- | |
| # Directories | |
| # ------------------------------------------------------------------- | |
| BASE_DIR = Path(__file__).parent | |
| GENERATED_DIR = BASE_DIR / "generated_images" | |
| LOG_DIR = BASE_DIR / "logs" | |
| GENERATED_DIR.mkdir(exist_ok=True) | |
| LOG_DIR.mkdir(exist_ok=True) | |
| # ------------------------------------------------------------------- | |
| # Logging | |
| # ------------------------------------------------------------------- | |
| logging.basicConfig( | |
| filename=LOG_DIR / "app.log", | |
| level=logging.INFO, | |
| format="%(asctime)s | %(levelname)s | %(message)s", | |
| ) | |
| logger = logging.getLogger(__name__) | |
| # ------------------------------------------------------------------- | |
| # OpenAI Client | |
| # ------------------------------------------------------------------- | |
| client = OpenAI( | |
| api_key=os.getenv("OPENAI_API_KEY") | |
| ) | |
| # ------------------------------------------------------------------- | |
| # Prompt History | |
| # ------------------------------------------------------------------- | |
| prompt_history: List[str] = [] | |
| # ------------------------------------------------------------------- | |
| # Validation | |
| # ------------------------------------------------------------------- | |
| def validate_prompt(prompt: str) -> None: | |
| if not prompt or not prompt.strip(): | |
| raise ValueError("Prompt cannot be empty.") | |
| if len(prompt.strip()) < 3: | |
| raise ValueError("Prompt too short.") | |
| # ------------------------------------------------------------------- | |
| # Save Image | |
| # ------------------------------------------------------------------- | |
| def save_image(image: Image.Image) -> str: | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| filename = f"generated_{timestamp}.png" | |
| output_path = GENERATED_DIR / filename | |
| image.save(output_path) | |
| logger.info("Image saved: %s", output_path) | |
| return str(output_path) | |
| # ------------------------------------------------------------------- | |
| # Generate Image | |
| # ------------------------------------------------------------------- | |
| def generate_image( | |
| prompt: str, | |
| size: str = "1024x1024", | |
| quality: str = "high", | |
| style: str = "vivid", | |
| retries: int = 3, | |
| ) -> Tuple[str, List[str], str]: | |
| validate_prompt(prompt) | |
| prompt_history.append(prompt) | |
| for attempt in range(retries): | |
| try: | |
| logger.info("Generating image: %s", prompt) | |
| response = client.images.generate( | |
| model="gpt-image-1", | |
| prompt=prompt, | |
| size=size, | |
| quality=quality, | |
| n=1, | |
| ) | |
| image_base64 = response.data[0].b64_json | |
| image_bytes = base64.b64decode(image_base64) | |
| image = Image.open(BytesIO(image_bytes)) | |
| image_path = save_image(image) | |
| return ( | |
| image_path, | |
| prompt_history[-10:], | |
| "✅ Image generated successfully!", | |
| ) | |
| except Exception as error: | |
| logger.error("Generation failed: %s", error) | |
| if attempt == retries - 1: | |
| return ( | |
| None, | |
| prompt_history[-10:], | |
| f"❌ Error: {error}", | |
| ) | |
| time.sleep(2) | |
| return ( | |
| None, | |
| prompt_history[-10:], | |
| "❌ Unknown error occurred.", | |
| ) | |
| # ------------------------------------------------------------------- | |
| # Clear History | |
| # ------------------------------------------------------------------- | |
| def clear_history(): | |
| prompt_history.clear() | |
| return [] | |
| """Main launcher for Gradio app.""" | |
| from UI import build_demo | |
| from app import clear_history, generate_image | |
| demo = build_demo() | |
| demo.queue() | |
| demo.launch() | |