OpenEnvHackathon / src /server.py
TheAllanB's picture
Add interactive frontend: radar demo + live API + results dashboard
2c80dff
Raw
History Blame Contribute Delete
1.84 kB
from __future__ import annotations
from dataclasses import asdict
from pathlib import Path
from typing import Optional
from fastapi import FastAPI, HTTPException
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from pydantic import BaseModel
from .environment import TicketmeltEnv
from .models import Action, Observation
app = FastAPI(title="TicketMelt", version="0.1.0")
_env = TicketmeltEnv()
_static_dir = Path(__file__).parent.parent / "static"
app.mount("/static", StaticFiles(directory=str(_static_dir)), name="static")
@app.get("/")
async def root():
return FileResponse(str(_static_dir / "index.html"))
class ResetRequest(BaseModel):
seed: Optional[int] = None
class StepRequest(BaseModel):
commitment: str
channel_msg: str = ""
def _obs_to_dict(obs: Observation) -> dict:
return {
"current_round": obs.current_round,
"total_rounds": obs.total_rounds,
"my_service": asdict(obs.my_service),
"my_engineer_name": obs.my_engineer_name,
"peer_progress": obs.peer_progress,
"history": [asdict(r) for r in obs.history],
"done": obs.done,
}
@app.get("/health")
def health():
return {"status": "ok"}
@app.post("/reset")
def reset(req: ResetRequest = None):
seed = req.seed if req is not None else None
obs = _env.reset(seed=seed)
return _obs_to_dict(obs)
@app.post("/step")
def step(req: StepRequest):
try:
action = Action(commitment=req.commitment, channel_msg=req.channel_msg)
obs, reward, done, info = _env.step(action)
return {"observation": _obs_to_dict(obs), "reward": reward, "done": done, "info": info}
except RuntimeError as e:
raise HTTPException(status_code=400, detail=str(e))
@app.get("/state")
def state():
return _env.state()