import logging import httpx _logger = logging.getLogger(__name__) ELAI_BASE_URL = "https://apis.elai.io/api/v1/videos" class EncoachElaiService: def __init__(self, env): self.env = env self.token = ( env["ir.config_parameter"] .sudo() .get_param("encoach.elai_token", "") ) def _headers(self): return { "Authorization": f"Bearer {self.token}", "Content-Type": "application/json", } def create_video(self, text, avatar_code): """Create and render an ELAI video. Returns the video_id for status polling, or None on failure. """ avatar = ( self.env["encoach.elai.avatar"] .sudo() .search([("avatar_code", "=", avatar_code)], limit=1) ) if not avatar: _logger.error("Avatar not found: %s", avatar_code) return None payload = { "name": f"EnCoach Speaking - {avatar.name}", "slides": [ { "avatar": { "code": avatar.avatar_code, "canvas": avatar.canvas or "default", "voiceId": avatar.voice_id or "", "voiceProvider": avatar.voice_provider or "", }, "speech": text, }, ], } try: resp = httpx.post( ELAI_BASE_URL, headers=self._headers(), json=payload, timeout=30, ) resp.raise_for_status() data = resp.json() video_id = data.get("_id") or data.get("id") self._render_video(video_id) return video_id except Exception: _logger.exception("ELAI video creation failed") return None def _render_video(self, video_id): try: httpx.post( f"{ELAI_BASE_URL}/render/{video_id}", headers=self._headers(), timeout=30, ) except Exception: _logger.exception("ELAI render request failed for %s", video_id) def poll_status(self, video_id): """Poll ELAI for video rendering status. Returns dict with 'status' and optionally 'url' keys. """ try: resp = httpx.get( f"{ELAI_BASE_URL}/{video_id}", headers=self._headers(), timeout=30, ) resp.raise_for_status() data = resp.json() status = data.get("status", "unknown") result = {"status": status} if status == "ready": result["url"] = data.get("url", "") return result except Exception: _logger.exception("ELAI status poll failed for %s", video_id) return {"status": "error"} def get_avatars(self): """List all configured ELAI avatars.""" avatars = self.env["encoach.elai.avatar"].sudo().search([]) return [a.to_encoach_dict() for a in avatars]