Spaces:
Running
Running
| # Copyright (c) Meta Platforms, Inc. and affiliates. | |
| # All rights reserved. | |
| # | |
| # This source code is licensed under the BSD-style license found in the | |
| # LICENSE file in the root directory of this source tree. | |
| """ | |
| FastAPI application for the Explainer Env Environment. | |
| This module creates an HTTP server that exposes the ExplainerEnvironment | |
| over HTTP and WebSocket endpoints, compatible with EnvClient. | |
| 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 | |
| Usage: | |
| # Development (with auto-reload): | |
| uvicorn server.app:app --reload --host 0.0.0.0 --port 8000 | |
| # Production: | |
| uvicorn server.app:app --host 0.0.0.0 --port 8000 --workers 4 | |
| # Or run directly: | |
| python -m server.app | |
| """ | |
| import os | |
| from contextlib import asynccontextmanager | |
| 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 '\n uv sync\n'") from e | |
| try: | |
| from ..models import ExplainerAction, ExplainerObservation | |
| from ..research.retrieval import EMBEDDING_CACHE_DIR, EMBEDDING_MODEL_NAME, preload_embedding_model | |
| from .explainer_env_environment import ExplainerEnvironment | |
| except ImportError: | |
| from models import ExplainerAction, ExplainerObservation | |
| from research.retrieval import EMBEDDING_CACHE_DIR, EMBEDDING_MODEL_NAME, preload_embedding_model | |
| from server.explainer_env_environment import ExplainerEnvironment | |
| def _build_dashboard_tab(*_args, **_kwargs): | |
| """Return the project dashboard as an OpenEnv custom web-interface tab.""" | |
| try: | |
| from ..dashboard import build_ui | |
| except ImportError: # pragma: no cover - supports uvicorn server.app:app | |
| from dashboard import build_ui | |
| return build_ui() | |
| # Serve the dashboard from the same FastAPI service by default. OpenEnv only | |
| # attaches gradio_builder when its web interface is enabled. | |
| os.environ.setdefault("ENABLE_WEB_INTERFACE", "true") | |
| # Create the app with web interface, README integration, and the dashboard tab. | |
| app = create_app( | |
| ExplainerEnvironment, | |
| ExplainerAction, | |
| ExplainerObservation, | |
| env_name="explainer_env", | |
| max_concurrent_envs=4, # parallel training rollouts | |
| gradio_builder=_build_dashboard_tab, | |
| ) | |
| _base_lifespan = app.router.lifespan_context | |
| async def _lifespan(app_instance): | |
| """Block startup until the embedding model is downloaded and initialized.""" | |
| preload_embedding_model() | |
| print( | |
| f"Embedding model ready: {EMBEDDING_MODEL_NAME} " | |
| f"(cache={EMBEDDING_CACHE_DIR})", | |
| flush=True, | |
| ) | |
| async with _base_lifespan(app_instance): | |
| yield | |
| app.router.lifespan_context = _lifespan | |
| def main(host: str = "0.0.0.0", port: int = 8000): | |
| """ | |
| Entry point for direct execution via uv run or python -m. | |
| This function enables running the server without Docker: | |
| uv run --project . server | |
| uv run --project . server --port 8001 | |
| python -m explainer_env.server.app | |
| Args: | |
| host: Host address to bind to (default: "0.0.0.0") | |
| port: Port number to listen on (default: 8000) | |
| """ | |
| import uvicorn | |
| uvicorn.run(app, host=host, port=port) | |
| if __name__ == "__main__": | |
| main() | |