Spaces:
Sleeping
Sleeping
| import uvicorn | |
| from fastapi import FastAPI | |
| from pydantic import BaseModel | |
| from typing import List, Dict, Any | |
| from env import EmailSortingEnv | |
| app = FastAPI( | |
| title="Email Sorting OpenEnv", | |
| description="Real-world email sorting environment for RL agents", | |
| version="1.0.0" | |
| ) | |
| env = EmailSortingEnv() | |
| # ============================================ | |
| # PYDANTIC MODELS — typed Observation, Action, Reward | |
| # ============================================ | |
| class EmailModel(BaseModel): | |
| subject: str | |
| body: str | |
| sender: str | |
| class Observation(BaseModel): | |
| email: EmailModel | |
| step: int | |
| max_steps: int | |
| total_reward: float | |
| done: bool | |
| valid_actions: List[str] | |
| class StepRequest(BaseModel): | |
| action: str | |
| class StepResponse(BaseModel): | |
| observation: Observation | |
| reward: float | |
| done: bool | |
| info: Dict[str, Any] | |
| class ResetResponse(BaseModel): | |
| observation: Observation | |
| class GraderTask(BaseModel): | |
| task_id: str | |
| score: float | |
| class GradersResponse(BaseModel): | |
| tasks: List[GraderTask] | |
| average_score: float | |
| # ============================================ | |
| # API ENDPOINTS | |
| # ============================================ | |
| def health_check(): | |
| return {"status": "ok", "message": "Email Sorting Environment is running"} | |
| def root(): | |
| return { | |
| "name": "Email Sorting OpenEnv", | |
| "version": "1.0.0", | |
| "description": "Sort emails as spam, important, or promotion", | |
| "endpoints": ["/reset", "/step", "/state", "/graders", "/health"] | |
| } | |
| def reset(): | |
| """Reset environment and return initial observation.""" | |
| state = env.reset() | |
| return ResetResponse(observation=Observation(**state)) | |
| def step(request: StepRequest): | |
| """Take action and return next observation, reward, done, info.""" | |
| next_state, reward, done, info = env.step(request.action) | |
| return StepResponse( | |
| observation=Observation(**next_state), | |
| reward=reward, | |
| done=done, | |
| info=info | |
| ) | |
| def get_state(): | |
| """Return current observation without taking action.""" | |
| return ResetResponse(observation=Observation(**env.state())) | |
| def run_graders(): | |
| """Run all graders and return scores.""" | |
| from graders import grade_easy_sorting, grade_medium_sorting, grade_hard_sorting | |
| tasks = [ | |
| GraderTask(task_id="easy_sorting", score=grade_easy_sorting()), | |
| GraderTask(task_id="medium_sorting", score=grade_medium_sorting()), | |
| GraderTask(task_id="hard_sorting", score=grade_hard_sorting()), | |
| ] | |
| avg = round(sum(t.score for t in tasks) / len(tasks), 4) | |
| return GradersResponse(tasks=tasks, average_score=avg) | |
| def grade_easy(): | |
| from graders import grade_easy_sorting | |
| return {"task_id": "easy_sorting", "score": grade_easy_sorting()} | |
| def grade_medium(): | |
| from graders import grade_medium_sorting | |
| return {"task_id": "medium_sorting", "score": grade_medium_sorting()} | |
| def grade_hard(): | |
| from graders import grade_hard_sorting | |
| return {"task_id": "hard_sorting", "score": grade_hard_sorting()} | |
| # ============================================ | |
| # START SERVER | |
| # ============================================ | |
| if __name__ == "__main__": | |
| print("Starting Email Sorting Environment Server...") | |
| print("Server running at http://localhost:7860") | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |