BrowserUse_and_ComputerUse_.../api/clients/browser_rpc_client.py

52 lines
2.5 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._run_url = rpc_url.rstrip("/")
if self._run_url.endswith("/run"):
self._base_url = self._run_url[: -len("/run")]
else:
self._base_url = self._run_url
self._run_url = f"{self._base_url}/run"
self._session = session
async def _post_json(self, url: str, payload: dict[str, Any], timeout_sec: float | None = None) -> dict[str, Any]:
timeout = aiohttp.ClientTimeout(total=timeout_sec) if timeout_sec is not None else None
try:
async with self._session.post(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(self, task_id: str, task: str, timeout_sec: float) -> dict[str, Any]:
return await self._post_json(self._run_url, {"task_id": task_id, "task": task}, timeout_sec=timeout_sec)
async def verify_captcha(self, task_id: str) -> dict[str, Any]:
return await self._post_json(f"{self._base_url}/verify", {"task_id": task_id}, timeout_sec=15)
async def resume(self, task_id: str, timeout_sec: float) -> dict[str, Any]:
return await self._post_json(f"{self._base_url}/resume", {"task_id": task_id}, timeout_sec=timeout_sec)
async def abort(self, task_id: str, reason: str | None = None) -> dict[str, Any]:
return await self._post_json(f"{self._base_url}/abort", {"task_id": task_id, "reason": reason}, timeout_sec=15)
async def run_browser_task(rpc_url: str, task_id: str, task: str, timeout_sec: float) -> dict[str, Any]:
async with aiohttp.ClientSession() as session:
client = BrowserRpcClient(rpc_url, session=session)
return await client.run(task_id=task_id, task=task, timeout_sec=timeout_sec)