EcoGrid / server /app.py
Loosebag's picture
fix: stabilize deployment, action safety, and benchmark reproducibility
30bdd62
Raw
History Blame Contribute Delete
2.05 kB
import json
import os
try:
from openenv.core.env_server.http_server import create_app
except ImportError as e:
raise ImportError("openenv-core>=0.2.0 is required for the server.") from e
from fastapi import Request
from fastapi.responses import JSONResponse
from models.schemas import GridAction
from server.ecogrid_environment import ServerEcoGridEnv, ServerObservation
app = create_app(
ServerEcoGridEnv,
GridAction,
ServerObservation,
env_name="eco-grid-openenv",
max_concurrent_envs=10,
)
@app.middleware("http")
async def normalize_step_payload(request: Request, call_next):
"""Allow /step payloads with either wrapped or direct action JSON."""
if request.method == "POST" and request.url.path == "/step":
body = await request.body()
if body:
try:
payload = json.loads(body)
except json.JSONDecodeError:
return JSONResponse(status_code=422, content={"detail": "Invalid JSON body"})
if isinstance(payload, dict) and "action" not in payload:
wrapped = json.dumps({"action": payload}).encode("utf-8")
request._body = wrapped
async def _receive():
return {"type": "http.request", "body": wrapped, "more_body": False}
request._receive = _receive
return await call_next(request)
@app.get("/", include_in_schema=False)
def root():
"""Landing route for judges/operators."""
return JSONResponse(
{
"name": "eco-grid-openenv",
"status": "ok",
"docs": "/docs",
"health": "/health",
"schema": "/schema",
"version": "/version",
}
)
@app.get("/version", include_in_schema=False)
def version():
return {"version": "1.1.0-stabilized"}
def main():
import uvicorn
host = os.getenv("HOST", "0.0.0.0")
port = int(os.getenv("PORT", "7860"))
uvicorn.run(app, host=host, port=port)
if __name__ == "__main__":
main()