56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
from typing import Any
|
|
|
|
import aiohttp
|
|
|
|
from api.clients.browser_rpc_contracts import BrowserRpcError
|
|
|
|
|
|
class BrowserRpcClient:
|
|
def __init__(self, rpc_url: str, session: aiohttp.ClientSession) -> None:
|
|
self._rpc_url = rpc_url
|
|
self._session = session
|
|
|
|
async def run(
|
|
self,
|
|
task: str,
|
|
timeout_sec: float,
|
|
rpc_url: str | None = None,
|
|
task_id: str | None = None,
|
|
) -> dict[str, Any]:
|
|
payload: dict[str, Any] = {"task": task}
|
|
if task_id:
|
|
payload["task_id"] = task_id
|
|
timeout = aiohttp.ClientTimeout(total=timeout_sec)
|
|
target_url = rpc_url or self._rpc_url
|
|
|
|
try:
|
|
async with self._session.post(target_url, json=payload, timeout=timeout) as response:
|
|
if response.status >= 400:
|
|
body = await response.text()
|
|
raise BrowserRpcError(f"RPC HTTP: {response.status}: {body}")
|
|
|
|
try:
|
|
data = await response.json(content_type=None)
|
|
except aiohttp.ContentTypeError as exc:
|
|
raise BrowserRpcError("RPC returned non-JSON response") from exc
|
|
except aiohttp.ClientError as exc:
|
|
raise BrowserRpcError(f"Transport error: {exc}") from exc
|
|
|
|
if not isinstance(data, dict):
|
|
raise BrowserRpcError("RPC returned invalid payload type")
|
|
|
|
return data
|
|
|
|
|
|
async def run_browser_task(
|
|
rpc_url: str,
|
|
task: str,
|
|
timeout_sec: float,
|
|
task_id: str | None = None,
|
|
) -> dict[str, Any]:
|
|
async with aiohttp.ClientSession() as session:
|
|
return await BrowserRpcClient(rpc_url, session=session).run(
|
|
task=task,
|
|
timeout_sec=timeout_sec,
|
|
task_id=task_id,
|
|
)
|