my-env / client.py
TheOnlyKaks's picture
updation
75ca235
Raw
History Blame Contribute Delete
2.24 kB
"""Minimal API client for interacting with the Bug Triage OpenEnv server."""
from __future__ import annotations
import json
from typing import Any, Optional
from urllib import error, request
from models import ActionModel
class EnvClient:
"""Small HTTP client for reset/step/state calls."""
def __init__(self, base_url: str = "http://127.0.0.1:7860") -> None:
self.base_url = base_url.rstrip("/")
def _url(self, path: str) -> str:
return f"{self.base_url}/{path.lstrip('/')}"
def _request(
self,
method: str,
path: str,
payload: Optional[dict[str, Any]] = None,
) -> dict[str, Any]:
body = None
headers = {"Accept": "application/json"}
if payload is not None:
body = json.dumps(payload).encode("utf-8")
headers["Content-Type"] = "application/json"
req = request.Request(
url=self._url(path),
data=body,
headers=headers,
method=method.upper(),
)
try:
with request.urlopen(req, timeout=30) as response:
raw = response.read().decode("utf-8")
return json.loads(raw) if raw else {}
except error.HTTPError as exc:
details = exc.read().decode("utf-8", errors="replace")
raise RuntimeError(f"HTTP {exc.code} {exc.reason}: {details}") from exc
def reset(self, task_id: Optional[str] = None, seed: Optional[int] = None) -> dict[str, Any]:
payload: dict[str, Any] = {}
if task_id is not None:
payload["task_id"] = task_id
if seed is not None:
payload["seed"] = seed
return self._request("POST", "/reset", payload if payload else None)
def step(self, action: ActionModel) -> dict[str, Any]:
return self._request(
"POST",
"/step",
{"action": action.model_dump(mode="json", exclude_none=True)},
)
def state(self) -> dict[str, Any]:
return self._request("GET", "/state")
def tasks(self) -> dict[str, Any]:
return self._request("GET", "/tasks")
def health(self) -> dict[str, Any]:
return self._request("GET", "/health")