Spaces:
Runtime error
Runtime error
| from __future__ import annotations | |
| import glob | |
| import os | |
| from urllib.request import Request, urlopen | |
| from fastapi import Query | |
| from fastapi.responses import RedirectResponse | |
| from openenv.core.env_server import create_app | |
| from freeciv_env.adapter import prepare_observation | |
| from freeciv_env.models import FreecivAction, FreecivObservation | |
| from freeciv_env.runtime import DEBUG_EVENTS, LiveFreecivSession | |
| from freeciv_env.server.freeciv_environment import FreecivEnvironment | |
| def create_live_session() -> LiveFreecivSession: | |
| return LiveFreecivSession( | |
| username=os.getenv("FREECIV_USERNAME", "openenvbot"), | |
| client_port=int(os.getenv("FREECIV_CLIENT_PORT", "6000")), | |
| base_url=os.getenv("FREECIV_SERVER_URL", "http://127.0.0.1"), | |
| turn_timeout_s=float(os.getenv("FREECIV_TURN_TIMEOUT_S", "60")), | |
| ) | |
| def create_freeciv_app(*, session_factory=create_live_session, max_turns: int | None = None): | |
| if max_turns is None: | |
| max_turns = int(os.getenv("FREECIV_MAX_TURNS", "50")) | |
| return create_app( | |
| lambda: FreecivEnvironment(session_factory=session_factory, max_turns=max_turns), | |
| FreecivAction, | |
| FreecivObservation, | |
| env_name="freeciv_env", | |
| ) | |
| app = create_freeciv_app() | |
| def root() -> RedirectResponse: | |
| return RedirectResponse(url="/web") | |
| def debug_internal_status() -> dict: | |
| checks = [] | |
| for name, method, url in [ | |
| ("nginx", "GET", "http://127.0.0.1/"), | |
| ("publite2", "GET", "http://127.0.0.1/pubstatus"), | |
| ("tomcat", "GET", "http://127.0.0.1:8080/freeciv-web/"), | |
| ("proxy7000", "GET", "http://127.0.0.1/civsocket/7000/status"), | |
| ("proxy7001", "GET", "http://127.0.0.1/civsocket/7001/status"), | |
| ("proxy7002", "GET", "http://127.0.0.1/civsocket/7002/status"), | |
| ("launcher", "POST", "http://127.0.0.1/civclientlauncher?civserverport=6000"), | |
| ]: | |
| try: | |
| request = Request(url, method=method) | |
| with urlopen(request, timeout=10) as response: | |
| body = response.read(200).decode("utf-8", "ignore") | |
| checks.append( | |
| { | |
| "name": name, | |
| "ok": True, | |
| "status": response.status, | |
| "body": body, | |
| } | |
| ) | |
| except Exception as exc: | |
| checks.append({"name": name, "ok": False, "error": repr(exc)}) | |
| return {"checks": checks} | |
| def debug_live_log() -> dict: | |
| return {"events": list(DEBUG_EVENTS)} | |
| def debug_freeciv_logs() -> dict: | |
| logs = {} | |
| for path in sorted(glob.glob("/docker/logs/*.log"))[-12:]: | |
| try: | |
| with open(path, "r", encoding="utf-8", errors="ignore") as handle: | |
| lines = handle.readlines()[-80:] | |
| logs[path] = "".join(lines) | |
| except Exception as exc: | |
| logs[path] = repr(exc) | |
| return {"logs": logs} | |
| def debug_startup_log() -> dict: | |
| path = "/tmp/start_space.log" | |
| try: | |
| with open(path, "r", encoding="utf-8", errors="ignore") as handle: | |
| lines = handle.readlines()[-120:] | |
| return {"path": path, "log": "".join(lines)} | |
| except Exception as exc: | |
| return {"path": path, "error": repr(exc)} | |
| def debug_live_reset(timeout_s: float = Query(default=120.0, ge=10.0, le=300.0)) -> dict: | |
| session = create_live_session() | |
| session.turn_timeout_s = timeout_s | |
| try: | |
| reset_snapshot = session.reset() | |
| reset_observation = prepare_observation( | |
| reset_snapshot, | |
| reward=0.0, | |
| done=False, | |
| status="ready", | |
| metadata={}, | |
| ).observation | |
| next_snapshot = session.end_turn() | |
| next_observation = prepare_observation( | |
| next_snapshot, | |
| reward=0.0, | |
| done=False, | |
| status="ok", | |
| metadata={}, | |
| ).observation | |
| return { | |
| "ok": True, | |
| "reset": { | |
| "turn": reset_observation.turn, | |
| "legal_actions": len(reset_observation.legal_actions), | |
| "summary": reset_observation.summary, | |
| }, | |
| "step": { | |
| "turn": next_observation.turn, | |
| "legal_actions": len(next_observation.legal_actions), | |
| "summary": next_observation.summary, | |
| }, | |
| } | |
| except Exception as exc: | |
| return {"ok": False, "error": repr(exc)} | |
| finally: | |
| session.close() | |
| def main() -> None: | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=8000, ws_ping_interval=300, ws_ping_timeout=300) | |
| if __name__ == "__main__": | |
| main() | |