github-actions[bot]
Deploy to HF Space from 2e7e2d503b896377e0bf161a73314974dd7ee7d1
b8a331e
Raw
History Blame Contribute Delete
2.36 kB
"""
FastAPI server for the Data Cleaning environment.
Environment Variables:
DATA_CLEAN_TASKS_PATH: Path to tasks directory (default: /app/env/tasks)
DATA_CLEAN_MAX_STEPS: Maximum tool calls per episode (default: 30)
Usage:
uvicorn server.app:app --host 0.0.0.0 --port 8000
"""
import os
# Import create_app from the correct location
try:
from openenv.core.env_server import create_app
except ImportError:
from openenv.core.env_server.http_server import create_app
# Use the base CallToolAction - not a subclass - so the server's
# MCP action routing (list_tools, call_tool) works correctly.
# The serialization.py checks `action_cls in _MCP_ACTION_TYPES.values()`
# which requires an exact match, not a subclass.
from openenv.core.env_server.mcp_types import CallToolAction, CallToolObservation
from server.environment import DataCleanEnvironment
DEFAULT_TASKS_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "tasks")
TASKS_PATH = os.environ.get("DATA_CLEAN_TASKS_PATH", DEFAULT_TASKS_PATH)
if not os.path.exists(TASKS_PATH):
# Fall back to packaged tasks if the provided env var path is invalid.
TASKS_PATH = DEFAULT_TASKS_PATH
MAX_STEPS = int(os.environ.get("DATA_CLEAN_MAX_STEPS", "30"))
def _env_factory():
"""Create a new DataCleanEnvironment instance for each session."""
return DataCleanEnvironment(
tasks_path=TASKS_PATH,
max_steps=MAX_STEPS,
)
# Create the FastAPI app
# IMPORTANT: Use base CallToolAction, not a custom subclass.
# The server's deserialize_action() only recognizes MCP actions
# (list_tools, call_tool) when action_cls is exactly one of the
# MCP action types or the base Action class.
app = create_app(
_env_factory,
CallToolAction, # Use base class, not custom subclass
CallToolObservation,
env_name="data_clean_env",
)
# Explicit health/info routes for platform checks.
@app.get("/health")
def health():
return {
"status": "ok",
"env_name": "data_clean_env",
"tasks_path": TASKS_PATH,
}
@app.get("/")
def root():
return {
"name": "data_clean_env",
"status": "running",
"health": "/health",
}
def main():
"""Entry point for running the server."""
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
if __name__ == "__main__":
main()