thomasm6m6's picture
Start app immediately and redirect root
1c0fdcc verified
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()
@app.get("/", include_in_schema=False)
def root() -> RedirectResponse:
return RedirectResponse(url="/web")
@app.get("/debug/internal-status")
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}
@app.get("/debug/live-log")
def debug_live_log() -> dict:
return {"events": list(DEBUG_EVENTS)}
@app.get("/debug/freeciv-logs")
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}
@app.get("/debug/startup-log")
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)}
@app.post("/debug/live-reset")
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()