feat: add HTML home page with nav to UI and docs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gilesb
2026-01-07 14:13:56 +00:00
parent 56d6f53695
commit dc9c13ffd9

102
server.py
View File

@@ -110,9 +110,9 @@ def cache_file(source: Path) -> str:
return content_hash
@app.get("/")
async def root():
"""Server info."""
@app.get("/api")
async def api_info():
"""Server info (JSON)."""
return {
"name": "Art DAG L1 Server",
"version": "0.1.0",
@@ -121,6 +121,102 @@ async def root():
}
HOME_HTML = """
<!DOCTYPE html>
<html>
<head>
<title>Art DAG L1 Server</title>
<style>
* { box-sizing: border-box; }
body {
font-family: system-ui, -apple-system, sans-serif;
margin: 0; padding: 40px;
background: #111; color: #eee;
line-height: 1.6;
}
.container { max-width: 800px; margin: 0 auto; }
h1 { color: #fff; border-bottom: 1px solid #333; padding-bottom: 10px; }
h2 { color: #ccc; margin-top: 30px; }
a { color: #60a5fa; }
a:hover { color: #93c5fd; }
code {
background: #222; padding: 2px 6px; border-radius: 4px;
font-family: 'SF Mono', Monaco, monospace;
}
pre {
background: #1a1a1a; padding: 16px; border-radius: 8px;
overflow-x: auto; border: 1px solid #333;
}
pre code { background: none; padding: 0; }
table { border-collapse: collapse; width: 100%; margin: 16px 0; }
th, td { border: 1px solid #333; padding: 8px 12px; text-align: left; }
th { background: #222; }
.nav {
background: #1a1a1a; padding: 16px; border-radius: 8px;
margin-bottom: 30px; display: flex; gap: 20px;
}
.nav a {
font-weight: 500; text-decoration: none;
padding: 8px 16px; background: #333; border-radius: 4px;
}
.nav a:hover { background: #444; }
</style>
</head>
<body>
<div class="container">
<div class="nav">
<a href="/ui">Runs UI</a>
<a href="/docs">API Docs</a>
<a href="/api">API Info</a>
</div>
<h1>Art DAG L1 Server</h1>
<p>L1 rendering server for the Art DAG system. Manages distributed rendering jobs via Celery workers.</p>
<h2>Dependencies</h2>
<ul>
<li><strong>artdag</strong> (GitHub): Core DAG execution engine</li>
<li><strong>artdag-effects</strong> (rose-ash): Effect implementations</li>
<li><strong>Redis</strong>: Message broker, result backend, and run persistence</li>
</ul>
<h2>API Endpoints</h2>
<table>
<tr><th>Method</th><th>Path</th><th>Description</th></tr>
<tr><td>GET</td><td><code>/ui</code></td><td>Web UI for viewing runs</td></tr>
<tr><td>POST</td><td><code>/runs</code></td><td>Start a rendering run</td></tr>
<tr><td>GET</td><td><code>/runs</code></td><td>List all runs</td></tr>
<tr><td>GET</td><td><code>/runs/{run_id}</code></td><td>Get run status</td></tr>
<tr><td>GET</td><td><code>/cache</code></td><td>List cached content hashes</td></tr>
<tr><td>GET</td><td><code>/cache/{hash}</code></td><td>Download cached content</td></tr>
<tr><td>POST</td><td><code>/cache/upload</code></td><td>Upload file to cache</td></tr>
<tr><td>GET</td><td><code>/assets</code></td><td>List known assets</td></tr>
</table>
<h2>Start a Run</h2>
<pre><code>curl -X POST /runs \\
-H "Content-Type: application/json" \\
-d '{"recipe": "dog", "inputs": ["33268b6e..."]}'</code></pre>
<h2>Provenance</h2>
<p>Every render produces a provenance record linking inputs, effects, and infrastructure:</p>
<pre><code>{
"output": {"content_hash": "..."},
"inputs": [...],
"effects": [...],
"infrastructure": {...}
}</code></pre>
</div>
</body>
</html>
"""
@app.get("/", response_class=HTMLResponse)
async def root():
"""Home page."""
return HOME_HTML
@app.post("/runs", response_model=RunStatus)
async def create_run(request: RunRequest):
"""Start a new rendering run."""