Spaces:
Sleeping
Sleeping
| """CloudSense Python SDK — typed client for the CloudSense RL environment.""" | |
| from __future__ import annotations | |
| import requests | |
| from env.models import ( | |
| ActionType, | |
| CloudAction, | |
| CloudObservation, | |
| CloudSenseAction, | |
| CloudSenseObservation, | |
| StepResult, | |
| ) | |
| class CloudSenseClient: | |
| """Typed HTTP client for the CloudSense environment API.""" | |
| def __init__(self, base_url: str = "http://localhost:7860"): | |
| self.base_url = base_url.rstrip("/") | |
| self._session = requests.Session() | |
| # ── Core environment API ──────────────────────────────────────── | |
| def reset(self, task_id: str = "startup-cleanup") -> CloudObservation: | |
| """Reset the environment to a new episode.""" | |
| resp = self._session.post( | |
| f"{self.base_url}/reset", | |
| params={"task_id": task_id}, | |
| timeout=30, | |
| ) | |
| resp.raise_for_status() | |
| return CloudObservation(**resp.json()) | |
| def step(self, action: CloudAction) -> StepResult: | |
| """Execute an action and return the result.""" | |
| resp = self._session.post( | |
| f"{self.base_url}/step", | |
| json=action.model_dump(), | |
| timeout=30, | |
| ) | |
| resp.raise_for_status() | |
| data = resp.json() | |
| return StepResult( | |
| observation=CloudObservation(**data["observation"]), | |
| reward=data["reward"], | |
| done=data["done"], | |
| info=data.get("info", {}), | |
| ) | |
| def state(self) -> dict: | |
| """Get the current environment state.""" | |
| resp = self._session.get(f"{self.base_url}/state", timeout=10) | |
| resp.raise_for_status() | |
| return resp.json() | |
| def close(self) -> None: | |
| """Close the current episode.""" | |
| resp = self._session.post(f"{self.base_url}/close", timeout=10) | |
| resp.raise_for_status() | |
| # ── Discovery ─────────────────────────────────────────────────── | |
| def health(self) -> dict: | |
| """Check environment health.""" | |
| resp = self._session.get(f"{self.base_url}/health", timeout=10) | |
| resp.raise_for_status() | |
| return resp.json() | |
| def tasks(self) -> list[dict]: | |
| """List available tasks.""" | |
| resp = self._session.get(f"{self.base_url}/tasks", timeout=10) | |
| resp.raise_for_status() | |
| return resp.json() | |
| # ── Convenience ───────────────────────────────────────────────── | |
| def rightsize( | |
| self, resource_id: str, instance_type: str, reasoning: str = "", **config | |
| ) -> StepResult: | |
| """Shortcut: rightsize a resource.""" | |
| new_config = {"instance_type": instance_type, **config} | |
| return self.step( | |
| CloudAction( | |
| action_type=ActionType.rightsize_resource, | |
| resource_id=resource_id, | |
| new_config=new_config, | |
| reasoning=reasoning, | |
| ) | |
| ) | |
| def terminate(self, resource_id: str, reasoning: str = "") -> StepResult: | |
| """Shortcut: terminate a resource.""" | |
| return self.step( | |
| CloudAction( | |
| action_type=ActionType.terminate_resource, | |
| resource_id=resource_id, | |
| reasoning=reasoning, | |
| ) | |
| ) | |
| def skip(self, resource_id: str, reasoning: str = "") -> StepResult: | |
| """Shortcut: skip a resource.""" | |
| return self.step( | |
| CloudAction( | |
| action_type=ActionType.skip_resource, | |
| resource_id=resource_id, | |
| reasoning=reasoning, | |
| ) | |
| ) | |