Tarkeshwar Claude Opus 4.6 (1M context) commited on
Commit
bb2fc43
·
1 Parent(s): bdb516f

Fix stateful HTTP endpoints and add HF Spaces deployment config

Browse files

- Add HF Spaces YAML frontmatter to README.md (sdk: docker, app_port: 8000)
- Rewrite app.py to use stateful shared environment instance instead of
framework's stateless per-request design
- Fix inference.py step payload to use {"action": {"command": ...}} format

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Files changed (3) hide show
  1. README.md +9 -0
  2. data_clean_env/server/app.py +70 -7
  3. inference.py +1 -1
README.md CHANGED
@@ -1,3 +1,12 @@
 
 
 
 
 
 
 
 
 
1
  # DataCleanEnv — Data Quality Analysis & Cleaning Environment
2
 
3
  A real-world OpenEnv environment where AI agents learn to identify and fix data quality issues through iterative inspection, correction, and validation.
 
1
+ ---
2
+ title: DataCleanEnv
3
+ emoji: 🧹
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: docker
7
+ app_port: 8000
8
+ ---
9
+
10
  # DataCleanEnv — Data Quality Analysis & Cleaning Environment
11
 
12
  A real-world OpenEnv environment where AI agents learn to identify and fix data quality issues through iterative inspection, correction, and validation.
data_clean_env/server/app.py CHANGED
@@ -1,6 +1,9 @@
1
  """FastAPI application for the DataClean Environment."""
2
 
3
- from openenv.core.env_server.http_server import create_app
 
 
 
4
 
5
  try:
6
  from .environment import DataCleanEnvironment
@@ -11,12 +14,72 @@ except ImportError:
11
  from server.environment import DataCleanEnvironment
12
  from models import DataCleanAction, DataCleanObservation
13
 
14
- app = create_app(
15
- DataCleanEnvironment,
16
- DataCleanAction,
17
- DataCleanObservation,
18
- env_name="data_clean_env",
19
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
 
22
  def main():
 
1
  """FastAPI application for the DataClean Environment."""
2
 
3
+ from fastapi import FastAPI, Body
4
+ from fastapi.responses import JSONResponse
5
+ from pydantic import BaseModel
6
+ from typing import Any, Dict, List, Optional
7
 
8
  try:
9
  from .environment import DataCleanEnvironment
 
14
  from server.environment import DataCleanEnvironment
15
  from models import DataCleanAction, DataCleanObservation
16
 
17
+ app = FastAPI(title="DataCleanEnv", version="1.0.0")
18
+
19
+ # Shared stateful environment instance
20
+ _env = DataCleanEnvironment()
21
+
22
+
23
+ # ---------------------------------------------------------------------------
24
+ # Request / response models
25
+ # ---------------------------------------------------------------------------
26
+ class ResetRequest(BaseModel):
27
+ task_id: str = "customer_contacts"
28
+ seed: Optional[int] = None
29
+ episode_id: Optional[str] = None
30
+ model_config = {"extra": "allow"}
31
+
32
+
33
+ class StepRequest(BaseModel):
34
+ action: Dict[str, Any]
35
+ model_config = {"extra": "allow"}
36
+
37
+
38
+ def _obs_dict(obs: DataCleanObservation) -> dict:
39
+ return obs.model_dump()
40
+
41
+
42
+ # ---------------------------------------------------------------------------
43
+ # Endpoints
44
+ # ---------------------------------------------------------------------------
45
+ @app.get("/health")
46
+ async def health():
47
+ return {"status": "ok"}
48
+
49
+
50
+ @app.post("/reset")
51
+ async def reset(request: ResetRequest = Body(default_factory=ResetRequest)):
52
+ obs = _env.reset(seed=request.seed, episode_id=request.episode_id, task_id=request.task_id)
53
+ return {"observation": _obs_dict(obs), "reward": None, "done": False}
54
+
55
+
56
+ @app.post("/step")
57
+ async def step(request: StepRequest):
58
+ action = DataCleanAction(**request.action)
59
+ obs = _env.step(action)
60
+ return {"observation": _obs_dict(obs), "reward": obs.reward, "done": obs.done}
61
+
62
+
63
+ @app.get("/state")
64
+ async def state():
65
+ return _env.state.model_dump()
66
+
67
+
68
+ @app.get("/metadata")
69
+ async def metadata():
70
+ return {
71
+ "env_name": "data_clean_env",
72
+ "action_schema": DataCleanAction.model_json_schema(),
73
+ "observation_schema": DataCleanObservation.model_json_schema(),
74
+ }
75
+
76
+
77
+ @app.get("/schema")
78
+ async def schema():
79
+ return {
80
+ "action": DataCleanAction.model_json_schema(),
81
+ "observation": DataCleanObservation.model_json_schema(),
82
+ }
83
 
84
 
85
  def main():
inference.py CHANGED
@@ -94,7 +94,7 @@ def env_step(command: str) -> Dict[str, Any]:
94
  """Execute a command in the environment."""
95
  resp = requests.post(
96
  f"{ENV_URL}/step",
97
- json={"command": command},
98
  timeout=30,
99
  )
100
  resp.raise_for_status()
 
94
  """Execute a command in the environment."""
95
  resp = requests.post(
96
  f"{ENV_URL}/step",
97
+ json={"action": {"command": command}},
98
  timeout=30,
99
  )
100
  resp.raise_for_status()