Spaces:
Sleeping
Sleeping
File size: 2,563 Bytes
ede2fa4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | """FastAPI server for the SQL Query Environment.
Exposes HTTP endpoints:
POST /reset - Start a new episode
POST /step - Submit a SQL query
GET /state - Get current state
GET /health - Health check
"""
import os
import sys
from typing import Optional
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
# Add parent + server to path for imports
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from models import SQLAction, SQLObservation
from sql_environment import SQLQueryEnvironment
# ββ Request/Response models ββ
class ResetRequest(BaseModel):
task_id: Optional[str] = "task_1"
class StepRequest(BaseModel):
task_id: str = "task_1"
sql_query: str = ""
# ββ Environment instance ββ
env = SQLQueryEnvironment()
app = FastAPI(
title="SQL Query Environment",
description=(
"An OpenEnv environment where AI agents learn to write SQL queries. "
"Features 3 tasks with increasing difficulty and deterministic grading."
),
version="1.0.0",
)
@app.get("/health")
async def health():
"""Health check endpoint."""
return {"status": "healthy"}
@app.post("/reset")
async def reset(request: ResetRequest = ResetRequest()):
"""Reset the environment and start a new episode."""
task_id = request.task_id or "task_1"
obs = env.reset(task_id=task_id)
return {
"observation": obs.model_dump(),
"reward": 0.0,
"done": False,
"info": {"episode_started": True, "task_id": task_id},
}
@app.post("/step")
async def step(request: StepRequest):
"""Submit a SQL query and get the result with grading."""
if not request.sql_query:
raise HTTPException(status_code=400, detail="sql_query is required")
action = SQLAction(task_id=request.task_id, sql_query=request.sql_query)
obs = env.step(action)
return {
"observation": obs.model_dump(),
"reward": obs.reward,
"done": obs.done,
"info": {
"step_count": obs.step_count,
"feedback": obs.feedback,
},
}
@app.get("/state")
async def get_state():
"""Get current episode state."""
s = env.state
return {
"episode_id": s.episode_id,
"step_count": s.step_count,
}
# ββ Run with uvicorn ββ
if __name__ == "__main__":
import uvicorn
port = int(os.environ.get("PORT", 7860))
uvicorn.run(app, host="0.0.0.0", port=port)
|