Taniieeee83 Claude Sonnet 4.6 commited on
Commit
498deff
·
1 Parent(s): 69e5273

Fix step endpoint to accept openenv-core wrapped action format and add GET /state

Browse files

- /step now accepts both {"action": {...}, "timeout_s": N} (openenv-core validator format)
and direct {"operation": "..."} (backward-compat for our client/inference)
- Add GET /state alongside POST /state to match openenv-core spec
- Update client.py state() to use GET /state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Files changed (2) hide show
  1. client.py +1 -1
  2. server/app.py +22 -7
client.py CHANGED
@@ -90,7 +90,7 @@ class DataCleaningEnvClient:
90
 
91
  def state(self) -> DataCleaningState:
92
  """Return current episode metadata without modifying state."""
93
- resp = self._client.post("/state")
94
  resp.raise_for_status()
95
  return DataCleaningState(**resp.json())
96
 
 
90
 
91
  def state(self) -> DataCleaningState:
92
  """Return current episode metadata without modifying state."""
93
+ resp = self._client.get("/state")
94
  resp.raise_for_status()
95
  return DataCleaningState(**resp.json())
96
 
server/app.py CHANGED
@@ -1,11 +1,11 @@
1
  """
2
  FastAPI application exposing the OpenEnv-compatible HTTP API.
3
  Endpoints: GET /health, GET /metadata, GET /schema,
4
- POST /reset, POST /step, POST /state, GET /docs
5
  """
6
 
7
- from typing import Optional
8
- from fastapi import FastAPI, HTTPException
9
  from pydantic import BaseModel
10
  import uvicorn
11
 
@@ -123,16 +123,31 @@ def reset(req: ResetRequest = ResetRequest()):
123
 
124
 
125
  @app.post("/step", response_model=StepResponse)
126
- def step(action: DataCleaningAction):
 
 
 
 
 
 
 
127
  try:
 
128
  obs = env.step(action)
129
- except RuntimeError as e:
130
  raise HTTPException(status_code=400, detail=str(e))
131
  return StepResponse(observation=obs, reward=obs.reward, done=obs.done)
132
 
133
 
 
 
 
 
 
 
134
  @app.post("/state", response_model=DataCleaningState)
135
- def state():
 
136
  return env.state()
137
 
138
 
@@ -145,4 +160,4 @@ def main():
145
 
146
 
147
  if __name__ == "__main__":
148
- main()
 
1
  """
2
  FastAPI application exposing the OpenEnv-compatible HTTP API.
3
  Endpoints: GET /health, GET /metadata, GET /schema,
4
+ POST /reset, POST /step, GET /state, POST /state, GET /docs
5
  """
6
 
7
+ from typing import Any, Dict, Optional
8
+ from fastapi import Body, FastAPI, HTTPException
9
  from pydantic import BaseModel
10
  import uvicorn
11
 
 
123
 
124
 
125
  @app.post("/step", response_model=StepResponse)
126
+ async def step(body: Dict[str, Any] = Body(...)):
127
+ """
128
+ Accept both openenv-core wrapped format:
129
+ {"action": {"operation": "...", ...}, "timeout_s": 15}
130
+ and direct format (for backward compat with our own client/inference):
131
+ {"operation": "...", "column": "...", "params": {...}}
132
+ """
133
+ action_data = body.get("action", body)
134
  try:
135
+ action = DataCleaningAction(**action_data)
136
  obs = env.step(action)
137
+ except (TypeError, KeyError, Exception) as e:
138
  raise HTTPException(status_code=400, detail=str(e))
139
  return StepResponse(observation=obs, reward=obs.reward, done=obs.done)
140
 
141
 
142
+ @app.get("/state", response_model=DataCleaningState)
143
+ def state_get():
144
+ """GET /state — openenv-core spec."""
145
+ return env.state()
146
+
147
+
148
  @app.post("/state", response_model=DataCleaningState)
149
+ def state_post():
150
+ """POST /state — backward compatibility."""
151
  return env.state()
152
 
153
 
 
160
 
161
 
162
  if __name__ == "__main__":
163
+ main()