CoolFace
Apppublic

AMD21/codefixerenv

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
app.py144 linesDownload Raw Back to server
1"""2server.py — FastAPI REST server for CodeFixerEnv.3 4Endpoints5---------6GET  /health        — liveness check7POST /reset         — start a new episode8POST /step          — submit an action9GET  /state         — inspect internal env state10GET  /tasks         — list all available tasks11 12All responses use Pydantic models for type-safe serialisation.13Hugging Face Spaces expects the server on port 7860.14"""15 16import os17import sys18sys.path.insert(0, os.path.dirname(__file__))19 20from fastapi import FastAPI, HTTPException21from fastapi.middleware.cors import CORSMiddleware22from pydantic import BaseModel23from typing import Optional24import uvicorn25 26from env.environment import CodeFixerEnv27from env.models import Action, Observation, Reward, StepResult28from tasks.tasks import TASKS29 30# ── App setup ─────────────────────────────────────────────────────────────────31app = FastAPI(32    title="CodeFixerEnv",33    description=(34        "OpenEnv environment for code-debugging RL tasks. "35        "An agent receives buggy Python code and must submit corrected solutions."36    ),37    version="1.0.0",38    docs_url="/docs",39    redoc_url="/redoc",40)41 42app.add_middleware(43    CORSMiddleware,44    allow_origins=["*"],45    allow_methods=["*"],46    allow_headers=["*"],47)48 49# Single shared environment instance (one session at a time)50env = CodeFixerEnv()51 52 53# ── Request/response schemas ──────────────────────────────────────────────────54class ResetRequest(BaseModel):55    difficulty: Optional[str] = "easy"56 57 58class StepRequest(BaseModel):59    action_type: str60    action_content: str61 62 63class StepResponse(BaseModel):64    observation: Observation65    reward: Reward66    done: bool67    info: dict68 69 70class TaskInfo(BaseModel):71    id: str72    difficulty: str73    context: str74 75 76# ── Endpoints ─────────────────────────────────────────────────────────────────77@app.get("/health")78def health():79    """Liveness check — returns 200 if the server is up."""80    return {"status": "ok", "environment": "CodeFixerEnv", "version": "1.0.0"}81 82 83@app.post("/reset", response_model=Observation)84def reset(request: ResetRequest):85    """86    Start a new episode.87 88    Body: { "difficulty": "easy" | "medium" | "hard" }89    Returns the initial Observation.90    """91    try:92        obs = env.reset(difficulty=request.difficulty or "easy")93        return obs94    except ValueError as e:95        raise HTTPException(status_code=400, detail=str(e))96 97 98@app.post("/step", response_model=StepResponse)99def step(request: StepRequest):100    """101    Submit one action and advance the episode.102 103    Body: { "action_type": "fix"|"explain"|"give_up", "action_content": "..." }104    Returns observation, structured reward, done flag, and diagnostics.105    """106    try:107        action = Action(type=request.action_type, content=request.action_content)108        obs, reward, done, info = env.step(action)109        return StepResponse(observation=obs, reward=reward, done=done, info=info)110    except RuntimeError as e:111        raise HTTPException(status_code=400, detail=str(e))112    except Exception as e:113        raise HTTPException(status_code=500, detail=str(e))114 115 116@app.get("/state")117def state():118    """Return the current internal state of the environment (for debugging)."""119    return env.state()120 121 122@app.get("/tasks", response_model=list[TaskInfo])123def list_tasks():124    """List all available tasks with their IDs and descriptions."""125    return [126        TaskInfo(id=t["id"], difficulty=t["difficulty"], context=t["context"])127        for _, (t, _) in TASKS.items()128    ]129 130 131# ── Entry point ───────────────────────────────────────────────────────────────132if __name__ == "__main__":133    port = int(os.environ.get("PORT", 7860))134    uvicorn.run(app, host="0.0.0.0", port=port)135 136 137def main():138    import uvicorn139    port = int(os.environ.get("PORT", 7860))140    uvicorn.run(app, host="0.0.0.0", port=port)141 142if __name__ == "__main__":143    main()144