""" RunPod handler for Mongle feed generation. Input: { "input": { "appearance": {...}, "quest_ko": "공원에서 30분 달리기를 완료했어요!", "quest_en": "optional English scene prompt", "name": "optional_job_name", "feed_seed": 123 } } Output: { "name": "...", "quest": { "quest_ko": "...", "quest_en": "..." }, "feed_image": "" } """ import base64 import io import json import os import traceback from pathlib import Path import runpod from PIL import Image from test_text2feed_pipeline import DEFAULT_QUEST_KO, translate_quest from src.feed.feed_generator_1 import generate, load_pipeline, unload_pipeline OUTPUT_ROOT = Path("outputs/handler_feed") def _encode_png(image_or_path) -> str: if isinstance(image_or_path, (str, Path)): image = Image.open(image_or_path).convert("RGB") else: image = image_or_path.convert("RGB") buffer = io.BytesIO() image.save(buffer, format="PNG") return base64.b64encode(buffer.getvalue()).decode("utf-8") def _load_appearance(payload: dict): appearance = payload.get("appearance") if appearance is not None: if isinstance(appearance, str): return json.loads(appearance) return appearance appearance_path = payload.get("appearance_path") if appearance_path: return json.loads(Path(appearance_path).read_text(encoding="utf-8")) raise ValueError("Missing input.appearance or input.appearance_path.") def handler(event): payload = event.get("input", {}) if isinstance(event, dict) else {} name = payload.get("name") or "feed_job" out_dir = OUTPUT_ROOT / name out_dir.mkdir(parents=True, exist_ok=True) try: appearance = _load_appearance(payload) quest_ko = payload.get("quest_ko") or DEFAULT_QUEST_KO quest_en = payload.get("quest_en") or translate_quest(quest_ko) feed_seed = int(payload.get("feed_seed", payload.get("seed", 123))) pipe = load_pipeline() try: image = generate(appearance, quest_en, pipe, seed=feed_seed) finally: unload_pipeline(pipe) feed_path = out_dir / "feed.png" image.save(feed_path) quest = {"quest_ko": quest_ko, "quest_en": quest_en} result_data = { "name": name, "appearance": appearance, "quest": quest, "feed_image_path": str(feed_path).replace("\\", "/"), } (out_dir / "result.json").write_text( json.dumps(result_data, ensure_ascii=False, indent=2), encoding="utf-8", ) return { "name": name, "quest": quest, "feed_image": _encode_png(feed_path), "output_dir": str(out_dir).replace("\\", "/"), } except Exception: error_text = traceback.format_exc() (out_dir / "error.log").write_text(error_text, encoding="utf-8") return {"error": error_text, "name": name, "output_dir": str(out_dir).replace("\\", "/")} if os.getenv("RUNPOD_SERVERLESS", "1") == "1": runpod.serverless.start({"handler": handler})