SynthAudit-Env / server /openenv_compat.py
Timusgeorge's picture
feat: full project files — server, training, evaluation, models, outputs
a33aae2 verified
"""
OpenEnv Compatibility Shim
===========================
Minimal Environment ABC that mirrors the openenv-core interface.
Used for local dev on Python 3.9. In Docker/Colab (Python 3.10+),
the real openenv-core takes over automatically.
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any
class Environment(ABC):
"""Minimal OpenEnv Environment base class."""
@abstractmethod
def reset(self, **kwargs) -> Any:
...
@abstractmethod
def step(self, action: Any, **kwargs) -> Any:
...
@abstractmethod
def state(self) -> Any:
...
def create_app(env_factory, action_type, observation_type, max_concurrent_envs=1):
"""Create a FastAPI app wrapping the environment."""
from fastapi import FastAPI
import json
app = FastAPI(title="SynthAudit.Env")
envs = {}
@app.get("/health")
async def health():
return {"status": "ok"}
@app.post("/reset")
async def reset_env(body: dict = {}):
env = env_factory()
eid = id(env)
envs[eid] = env
obs = env.reset(**body)
return {"env_id": eid, "observation": obs.dict() if hasattr(obs, 'dict') else obs.model_dump()}
@app.post("/step/{env_id}")
async def step_env(env_id: int, action: dict):
env = envs.get(env_id)
if not env:
return {"error": "env not found"}
act = action_type(**action)
obs = env.step(act)
return {"observation": obs.dict() if hasattr(obs, 'dict') else obs.model_dump()}
@app.get("/state/{env_id}")
async def get_state(env_id: int):
env = envs.get(env_id)
if not env:
return {"error": "env not found"}
s = env.state()
return {"state": s.dict() if hasattr(s, 'dict') else s.model_dump()}
return app