"""FastAPI application for the Drug Target Validation Environment. Endpoints: - POST /reset: Reset the environment - POST /step: Execute an action - GET /state: Get current environment state - GET /schema: Get action/observation schemas - WS /ws: WebSocket endpoint for persistent sessions - GET / Demo UI """ import os from pathlib import Path try: from openenv.core.env_server.http_server import create_app except Exception as e: # pragma: no cover raise ImportError( "openenv is required for the web interface. " "Install dependencies with 'uv sync'" ) from e from fastapi.responses import HTMLResponse from models import DrugTargetAction, ValidationObservation from .hackathon_environment import DrugTargetEnvironment app = create_app( DrugTargetEnvironment, DrugTargetAction, ValidationObservation, env_name="drug_target_validation", max_concurrent_envs=int(os.environ.get("MAX_ENVS", "4")), ) DEMO_HTML = Path(__file__).resolve().parent.parent / "demo.html" @app.get("/", response_class=HTMLResponse) async def demo_ui(): if DEMO_HTML.exists(): return HTMLResponse(content=DEMO_HTML.read_text(), status_code=200) return HTMLResponse( content=( "

Drug Target Validation Env API

" "

Visit /docs for API documentation.

" ), status_code=200, ) def main(host: str = "0.0.0.0", port: int = None): import uvicorn if port is None: port = int(os.environ.get("PORT", "8000")) uvicorn.run(app, host=host, port=port) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument("--host", default="0.0.0.0") parser.add_argument("--port", type=int, default=None) args = parser.parse_args() main(host=args.host, port=args.port) # ── Mount the Gradio demo at /demo (env Space landing) ──────────────────── # Optional: the env Space ships a small Gradio Blocks UI at # ``space/env/gradio_demo.py``; mounting it here means a single Docker # image can serve both the OpenEnv HTTP API and the human-friendly # demo. Failures are degraded silently so a server-only deploy (no # gradio installed) still boots. try: # pragma: no cover - import-time best-effort import gradio as _gr # type: ignore from space.env.gradio_demo import build_gradio_demo as _build_gradio_demo _demo = _build_gradio_demo() if isinstance(_demo, _gr.Blocks): _gr.mount_gradio_app(app, _demo, path="/demo") except Exception: # pragma: no cover pass