"""Async client for the Langflow authoring server (visual designer). Only used for the authoring pipeline (list/export flows). Execution always goes through LFX (see lfx_client.py). """ from __future__ import annotations import httpx class LangflowError(Exception): pass class LangflowNotFound(LangflowError): pass class LangflowUnavailable(LangflowError): pass class LangflowClient: """Thin async wrapper around the Langflow `/api/v1/flows` endpoints.""" def __init__(self, base_url: str, api_key: str = "", timeout: float = 60.0) -> None: self.base_url = base_url.rstrip("/") self.api_key = api_key self.timeout = timeout def _headers(self) -> dict[str, str]: return {"x-api-key": self.api_key} if self.api_key else {} async def list_flows(self) -> list[dict]: """List flows (header mode keeps payloads small).""" try: async with httpx.AsyncClient( base_url=self.base_url, timeout=self.timeout, headers=self._headers() ) as client: response = await client.get("/api/v1/flows/", params={"header_flows": "true"}) if response.status_code == 404: raise LangflowNotFound("flow list not found") response.raise_for_status() data = response.json() return data if isinstance(data, list) else data.get("items", []) except httpx.HTTPStatusError as exc: raise LangflowError(f"Langflow error {exc.response.status_code}") from exc except httpx.HTTPError as exc: raise LangflowUnavailable(f"Langflow unreachable: {exc}") from exc async def export_flow(self, langflow_flow_id: str) -> dict: """Export one flow as Langflow JSON (FlowRead: id/name/description/data).""" try: async with httpx.AsyncClient( base_url=self.base_url, timeout=self.timeout, headers=self._headers() ) as client: response = await client.get(f"/api/v1/flows/{langflow_flow_id}") if response.status_code == 404: raise LangflowNotFound(f"flow {langflow_flow_id} not found") response.raise_for_status() return response.json() except httpx.HTTPStatusError as exc: raise LangflowError(f"Langflow error {exc.response.status_code}") from exc except httpx.HTTPError as exc: raise LangflowUnavailable(f"Langflow unreachable: {exc}") from exc