reality-divergence / image_client.py
prashantAI's picture
Wire up working Qwen/FLUX inference, fix Gradio 5 build, add safety fallbacks
f8c1b4a
Raw
History Blame Contribute Delete
4.11 kB
"""Image generation client via the Hugging Face Inference API (text_to_image)."""
from typing import Optional
from PIL import Image
try:
from huggingface_hub import InferenceClient
except ImportError:
InferenceClient = None
import config
class ImageGenerationClient:
"""Generate artifact images for alternate timelines via the HF Inference API."""
def __init__(self, hf_token: Optional[str] = None):
self.hf_token = hf_token or config.HF_TOKEN
self.model = config.MODEL_NAME_IMAGE
self.fallback_model = config.FALLBACK_IMAGE_MODEL
self.client = None
self.available = False
if not config.ENABLE_IMAGE_GEN:
return
if not InferenceClient:
print("[warn]huggingface_hub not installed; image generation disabled")
return
if not self.hf_token:
print("[warn]HF_TOKEN not set; image generation disabled")
return
try:
self.client = InferenceClient(token=self.hf_token, timeout=config.TIMEOUT_IMAGE)
self.available = True
except Exception as e:
print(f"[warn]Image client initialization failed: {e}")
self.available = False
def generate(self, prompt: str) -> Optional[Image.Image]:
"""Generate an image from a prompt, with a fallback model."""
if not self.available:
return None
try:
return self.client.text_to_image(prompt, model=self.model)
except Exception as e:
print(f"[warn]Primary image generation failed ({self.model}): {e}")
try:
return self.client.text_to_image(prompt, model=self.fallback_model)
except Exception as e:
print(f"[warn]Fallback image generation failed ({self.fallback_model}): {e}")
return None
def generate_artifact_newspaper(self, headline: str, subheading: str) -> Optional[Image.Image]:
"""Generate a vintage newspaper artifact."""
prompt = (
f'Vintage newspaper front page with headline "{headline}" and subheading '
f'"{subheading}". Aged paper, period typography, realistic newspaper layout.'
)
return self.generate(prompt)
def generate_artifact_product(self, product: str, context: str) -> Optional[Image.Image]:
"""Generate a product advertisement or packaging."""
prompt = (
f'Vintage product advertisement for "{product}" in a world where {context}. '
f"Period-appropriate packaging design, realistic product mockup, authentic styling."
)
return self.generate(prompt)
def generate_artifact_document(self, doc_type: str, context: str) -> Optional[Image.Image]:
"""Generate a historical document artifact."""
prompt = (
f"Historical {doc_type} from an alternate timeline where {context}. "
f"Aged paper, period authentic, realistic museum quality."
)
return self.generate(prompt)
# Global client instance
_image_client = None
def get_image_client() -> ImageGenerationClient:
"""Get or create the global image generation client."""
global _image_client
if _image_client is None:
_image_client = ImageGenerationClient()
return _image_client
def generate_artifact(artifact_type: str, **kwargs) -> Optional[Image.Image]:
"""Generate an artifact image by type."""
client = get_image_client()
if artifact_type == "newspaper":
return client.generate_artifact_newspaper(
kwargs.get("headline", "Alternate History"),
kwargs.get("subheading", "A world that never was"),
)
elif artifact_type == "product":
return client.generate_artifact_product(
kwargs.get("product", "Product"),
kwargs.get("context", "divergence occurred"),
)
elif artifact_type == "document":
return client.generate_artifact_document(
kwargs.get("doc_type", "document"),
kwargs.get("context", "divergence occurred"),
)
return None