MCPcopy Create free account
hub / github.com/CodeClash-ai/CodeClash / run_server

Function run_server

codeclash/replay/serve.py:26–104  ·  view source on GitHub ↗

Serve the folder's replays until interrupted, opening the index in a browser.

(folder: Path, tour: TournamentInfo, renderer: ReplayRenderer, port: int = 8000)

Source from the content-addressed store, hash-verified

24
25
26def run_server(folder: Path, tour: TournamentInfo, renderer: ReplayRenderer, port: int = 8000) -> None:
27 """Serve the folder's replays until interrupted, opening the index in a browser."""
28
29 def render_game(game) -> str:
30 payload = {
31 "arena": tour.arena,
32 "players": tour.players,
33 "round": game.round,
34 "sim": game.sim,
35 "round_winner": game.winner if game.winner is not None else tour.round_winners.get(game.round),
36 "rounds": tour.rounds,
37 "sims": tour.sims_per_round,
38 "games": len(tour.games),
39 "folder": tour.folder.name,
40 "matchup": game.group or None,
41 }
42 return base.build_page(renderer.parse(base.read_sim(game), tour.players), payload, renderer)
43
44 def error_page(game, exc) -> str:
45 source = game.member or (game.path.name if game.path else "?")
46 return (
47 '<!doctype html><meta charset="utf-8">'
48 "<body style='background:#0d1117;color:#e6edf3;font:14px system-ui;padding:24px'>"
49 f"<h2>Couldn't render round {game.round}, sim {game.sim}</h2>"
50 f"<p style='color:#8b949e'>source: <code>{html.escape(source)}</code></p>"
51 f"<pre style='color:#e5484d;white-space:pre-wrap'>{html.escape(type(exc).__name__)}: {html.escape(str(exc))}</pre>"
52 "<p><a style='color:#58a6ff' href='/'>&larr; back to index</a></p></body>"
53 )
54
55 class Handler(BaseHTTPRequestHandler):
56 def do_GET(self):
57 parsed = urllib.parse.urlparse(self.path)
58 if parsed.path in ("/", "/index.html"):
59 self._html(base.build_index(tour))
60 return
61 if parsed.path == "/game":
62 q = urllib.parse.parse_qs(parsed.query)
63 try:
64 idx = int(q["g"][0])
65 game = tour.games[idx]
66 except (KeyError, ValueError, IndexError):
67 self.send_error(404, "no such game")
68 return
69 try:
70 self._html(render_game(game))
71 except Exception as exc: # one bad game shouldn't take down the server
72 print(f"[replay] failed to render game {idx}: {type(exc).__name__}: {exc}")
73 self._html(error_page(game, exc), status=500)
74 return
75 self.send_error(404)
76
77 def _html(self, page: str, status: int = 200):
78 body = page.encode()
79 self.send_response(status)
80 self.send_header("Content-Type", "text/html; charset=utf-8")
81 self.send_header("Content-Length", str(len(body)))
82 self.end_headers()
83 self.wfile.write(body)

Callers 1

replayFunction · 0.90

Calls 1

_ServerClass · 0.85

Tested by

no test coverage detected