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
|
#!/usr/bin/env python3
"""
Playground demo service — stdlib HTTP status page on port 9090.
Registered behind doot's auth layer at /playground/.
Start: python3 playground/web/server.py
"""
import http.server
import json
import os
import platform
import socket
import time
from datetime import datetime, timezone
START_TIME = time.monotonic()
PORT = int(os.environ.get("PLAYGROUND_PORT", "9090"))
STATUS_HTML = """\
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Playground — System Status</title>
<style>
body {{ font-family: monospace; background: #0f111a; color: #cdd6f4; margin: 0; padding: 2rem; }}
h1 {{ color: #89b4fa; margin-bottom: 0.25rem; }}
.subtitle {{ color: #6c7086; font-size: 0.85rem; margin-bottom: 2rem; }}
table {{ border-collapse: collapse; width: 100%; max-width: 640px; }}
td {{ padding: 0.4rem 0.8rem; border-bottom: 1px solid #313244; }}
td:first-child {{ color: #a6e3a1; width: 200px; }}
.badge {{ display: inline-block; background: #1e6e3a; color: #a6e3a1;
padding: 0.1rem 0.5rem; border-radius: 3px; font-size: 0.8rem; }}
</style>
</head>
<body>
<h1>Playground</h1>
<p class="subtitle">doot service gateway demo — authenticated via doot session</p>
<table>
<tr><td>status</td><td><span class="badge">ok</span></td></tr>
<tr><td>hostname</td><td>{hostname}</td></tr>
<tr><td>python</td><td>{python}</td></tr>
<tr><td>platform</td><td>{platform}</td></tr>
<tr><td>uptime</td><td>{uptime}</td></tr>
<tr><td>server time</td><td>{now}</td></tr>
<tr><td>pid</td><td>{pid}</td></tr>
<tr><td>port</td><td>{port}</td></tr>
</table>
</body>
</html>
"""
def _uptime() -> str:
elapsed = int(time.monotonic() - START_TIME)
h, rem = divmod(elapsed, 3600)
m, s = divmod(rem, 60)
return f"{h}h {m}m {s}s"
class Handler(http.server.BaseHTTPRequestHandler):
def log_message(self, fmt, *args): # quieter logs
print(f"{self.address_string()} {fmt % args}")
def do_GET(self):
if self.path in ("/health", "/health/"):
body = json.dumps({"status": "ok", "uptime": _uptime()}).encode()
self._respond(200, "application/json", body)
return
html = STATUS_HTML.format(
hostname=socket.gethostname(),
python=platform.python_version(),
platform=platform.system() + " " + platform.release(),
uptime=_uptime(),
now=datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC"),
pid=os.getpid(),
port=PORT,
).encode()
self._respond(200, "text/html; charset=utf-8", html)
def _respond(self, code, content_type, body):
self.send_response(code)
self.send_header("Content-Type", content_type)
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
if __name__ == "__main__":
server = http.server.HTTPServer(("127.0.0.1", PORT), Handler)
print(f"playground listening on http://127.0.0.1:{PORT} (pid {os.getpid()})")
server.serve_forever()
|