Shreya2005-2005's picture
Smart Study Session Optimizer - OpenEnv Hackathon Round 1
64b4cae
Raw History Blame Contribute Delete
2.35 kB
# client.py
# A simple Python client for calling the environment server
# You could do this with httpx directly but wrapping it is cleaner
#
# Use this in inference.py or anywhere else you need to talk to the server
import httpx
from typing import Optional
from .models import Observation, StepResult, Action
class StudyEnvClient:
"""
HTTP client for the Study Optimizer environment server.
Usage:
client = StudyEnvClient("http://localhost:8000")
obs = client.reset()
result = client.step(0) # 0=study
"""
def __init__(self, base_url: str = "http://localhost:8000", timeout: float = 30.0):
self.base_url = base_url.rstrip("/")
self.timeout = timeout
# using httpx because requests doesn't support async
# TODO: add async versions of these methods later
self._client = httpx.Client(timeout=self.timeout)
def health(self) -> dict:
"""Quick check to see if the server is up."""
resp = self._client.get(f"{self.base_url}/health")
resp.raise_for_status()
return resp.json()
def reset(self, task_id: Optional[str] = None) -> Observation:
"""Reset environment and get first observation."""
payload = {}
if task_id:
payload["task_id"] = task_id
resp = self._client.post(f"{self.base_url}/reset", json=payload)
resp.raise_for_status()
data = resp.json()
# took me a while to figure this out - the server wraps in 'observation' key
if "observation" in data:
return Observation(**data["observation"])
return Observation(**data)
def step(self, action: int) -> StepResult:
"""Take an action and get the result."""
payload = {"action": action}
resp = self._client.post(f"{self.base_url}/step", json=payload)
resp.raise_for_status()
data = resp.json()
return StepResult(**data)
def get_state(self) -> dict:
"""Get the full current state of the environment."""
resp = self._client.get(f"{self.base_url}/state")
resp.raise_for_status()
return resp.json()
def close(self):
"""Clean up the HTTP client."""
self._client.close()
def __enter__(self):
return self
def __exit__(self, *args):
self.close()