Spaces:
Runtime error
Runtime error
File size: 3,454 Bytes
7fedc25 8c486a8 86c1c19 890f5f3 7fedc25 890f5f3 fda4cbc 8c486a8 890f5f3 8c486a8 86c1c19 fda4cbc 7fedc25 890f5f3 7fedc25 890f5f3 7fedc25 890f5f3 7fedc25 890f5f3 906af9d 7fedc25 86c1c19 890f5f3 0fd9230 aef9d26 0fd9230 aef9d26 890f5f3 a4d58ae 890f5f3 fda4cbc 8c486a8 7fedc25 890f5f3 3ea4118 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | """FastAPI application for OpenRange."""
from __future__ import annotations
import inspect
import logging
import os
from fastapi import FastAPI
logger = logging.getLogger(__name__)
def _extract_openenv_server(fastapp: FastAPI) -> object | None:
"""Best-effort extraction of OpenEnv's HTTPEnvServer from route closure."""
for route in fastapp.router.routes:
if getattr(route, "path", None) != "/ws":
continue
endpoint = getattr(route, "endpoint", None)
if endpoint is None:
continue
try:
closure = inspect.getclosurevars(endpoint)
except Exception:
continue
server = closure.nonlocals.get("self")
if server is not None and hasattr(server, "active_sessions"):
return server
return None
def create_app() -> FastAPI:
"""Create the OpenRange app through the canonical OpenEnv factory."""
from openenv.core.env_server import create_app as create_openenv_app
from open_range.models import RangeAction, RangeObservation
from open_range.server.environment import RangeEnvironment
runtime = None
runtime_enabled = os.getenv("OPENRANGE_ENABLE_MANAGED_RUNTIME", "").lower() in {
"1",
"true",
"yes",
} or bool(os.getenv("OPENRANGE_RUNTIME_MANIFEST"))
if runtime_enabled:
from open_range.server.runtime import ManagedSnapshotRuntime
runtime = ManagedSnapshotRuntime.from_env()
def env_factory() -> RangeEnvironment:
return RangeEnvironment(runtime=runtime)
fastapp = create_openenv_app(
env_factory,
RangeAction,
RangeObservation,
env_name="open_range",
)
openenv_server = _extract_openenv_server(fastapp)
if openenv_server is not None:
fastapp.state.openenv_server = openenv_server
# Mount custom Gradio dashboard at /dashboard (separate from the OpenEnv
# Playground at /web which provides interactive reset/step via the
# WebInterfaceManager's persistent environment instance).
try:
import gradio as gr
from open_range.server.gradio_ui import build_openrange_gradio_app
blocks = build_openrange_gradio_app(
web_manager=None,
action_fields=[],
metadata=None,
is_chat_env=False,
title="OpenRange",
quick_start_md="",
)
fastapp = gr.mount_gradio_app(fastapp, blocks, path="/dashboard")
except Exception:
pass # Gradio is optional
fastapp.state.env = env_factory()
if runtime is not None:
fastapp.state.runtime = runtime
# NOTE: Do NOT register runtime.start() as a startup event — it
# synchronously generates snapshots which blocks the health check on
# resource-constrained hardware (HF Spaces cpu-basic). The runtime
# lazy-starts on the first acquire_snapshot() call (triggered by reset()).
fastapp.add_event_handler("shutdown", runtime.stop)
try:
from open_range.server.console import console_router
fastapp.include_router(console_router)
except Exception:
pass # Console router is optional
return fastapp
def main() -> None:
"""Run the installed package entrypoint via uvicorn."""
import uvicorn
uvicorn.run("open_range.server.app:app", host="0.0.0.0", port=8000)
app = create_app()
if __name__ == "__main__":
main()
|