Spaces:
Running
Running
main - Revert to card grid, remove logs section, fix colours
Browse filesRemove log section and row layout. Cards back with top colour border,
bright RSS colours (#4ade80 / #fbbf24 / #f87171), compact sizing (~85px
tall) to fit above HF logs panel. Header on one line to save vertical
space. JS polls /stats every 5s.
main.py
CHANGED
|
@@ -5,7 +5,7 @@ from fastapi.responses import HTMLResponse
|
|
| 5 |
|
| 6 |
from models import RequestModel, ResponseModel
|
| 7 |
from similarity import (
|
| 8 |
-
check_similarity, get_all_memory_stats,
|
| 9 |
start_memory_stats_reporter, start_memory_trimmer,
|
| 10 |
)
|
| 11 |
|
|
@@ -29,71 +29,49 @@ _PAGE = ("""<!DOCTYPE html><html><head>
|
|
| 29 |
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@1,800&family=Inter:wght@400;500&display=swap" rel="stylesheet">
|
| 30 |
<style>
|
| 31 |
*{margin:0;padding:0;box-sizing:border-box}
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
padding:
|
| 35 |
h1{font-family:'Barlow Condensed',sans-serif;font-weight:800;font-style:italic;
|
| 36 |
-
font-size:1.85rem;color:#fff;letter-spacing:-.01em;line-height:1
|
| 37 |
-
.meta{color:#
|
| 38 |
-
|
| 39 |
-
.
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
.
|
| 43 |
-
|
| 44 |
-
border-left:2px solid var(--c);background:#0f172a;border-radius:0 5px 5px 0}
|
| 45 |
-
.pid{font-size:.65rem;color:#94a3b8;font-family:'SF Mono','Fira Code',monospace;
|
| 46 |
text-transform:uppercase;letter-spacing:.06em}
|
| 47 |
-
.
|
| 48 |
-
.
|
| 49 |
-
|
| 50 |
-
.
|
| 51 |
-
|
| 52 |
-
.
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
.log-body{flex:1;overflow-y:auto;font-family:'SF Mono','Fira Code',monospace;
|
| 56 |
-
font-size:.6rem;line-height:1.5;min-height:0}
|
| 57 |
-
.log-body::-webkit-scrollbar{width:3px}
|
| 58 |
-
.log-body::-webkit-scrollbar-thumb{background:#1f2937;border-radius:99px}
|
| 59 |
-
.ln{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
|
| 60 |
-
padding:.1rem 0;border-bottom:1px solid #0d1117}
|
| 61 |
-
.ts{color:#64748b}.info{color:#60a5fa}.warning{color:#fbbf24}
|
| 62 |
-
.error{color:#f87171}.msg{color:#cbd5e1}
|
| 63 |
-
</style></head><body>
|
| 64 |
<header>
|
| 65 |
-
<h1>Prozis Similarity Service</h1>
|
|
|
|
| 66 |
</header>
|
| 67 |
-
<div id="
|
| 68 |
-
<div class="log-wrap">
|
| 69 |
-
<div class="log-label">Logs</div>
|
| 70 |
-
<div id="logs" class="log-body"></div>
|
| 71 |
-
</div>
|
| 72 |
<script>
|
| 73 |
const MAX=__CACHE_MAX__;
|
| 74 |
-
function
|
| 75 |
-
function
|
| 76 |
-
|
| 77 |
-
const w=d.workers,gb=(w.reduce((s,x)=>s+x.rss_mb,0)/1024).toFixed(1);
|
| 78 |
document.getElementById('meta').innerHTML=
|
| 79 |
-
`<b>${
|
| 80 |
-
document.getElementById('
|
| 81 |
-
const c=col(
|
| 82 |
-
return `<div class="
|
| 83 |
-
`<div class="
|
| 84 |
-
`<
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
lb.innerHTML=d.logs.map(l=>{
|
| 88 |
-
const m=l.match(/^(\S+) (\S+) ([\s\S]*)$/);
|
| 89 |
-
if(!m) return `<div class="ln"><span class="msg">${esc(l)}</span></div>`;
|
| 90 |
-
const [,ts,lvl,msg]=m;
|
| 91 |
-
return `<div class="ln"><span class="ts">${esc(ts)}</span> `+
|
| 92 |
-
`<span class="${lvl.toLowerCase()}">${esc(lvl)}</span> `+
|
| 93 |
-
`<span class="msg">${esc(msg)}</span></div>`;
|
| 94 |
}).join('');
|
| 95 |
}
|
| 96 |
-
async function refresh(){try{const r=await fetch('/stats');render(await r.json())}catch(e){}}
|
| 97 |
refresh();setInterval(refresh,5000);
|
| 98 |
</script>
|
| 99 |
</body></html>""").replace("__CACHE_MAX__", str(_CACHE_MAX))
|
|
@@ -101,7 +79,7 @@ refresh();setInterval(refresh,5000);
|
|
| 101 |
|
| 102 |
@app.get("/stats", include_in_schema=False)
|
| 103 |
async def stats_endpoint():
|
| 104 |
-
return {"workers": get_all_memory_stats()
|
| 105 |
|
| 106 |
|
| 107 |
@app.get("/", include_in_schema=False)
|
|
|
|
| 5 |
|
| 6 |
from models import RequestModel, ResponseModel
|
| 7 |
from similarity import (
|
| 8 |
+
check_similarity, get_all_memory_stats,
|
| 9 |
start_memory_stats_reporter, start_memory_trimmer,
|
| 10 |
)
|
| 11 |
|
|
|
|
| 29 |
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@1,800&family=Inter:wght@400;500&display=swap" rel="stylesheet">
|
| 30 |
<style>
|
| 31 |
*{margin:0;padding:0;box-sizing:border-box}
|
| 32 |
+
body{background:#0d0d14;color:#e2e8f0;font-family:'Inter',system-ui,sans-serif;padding:.875rem 1.5rem}
|
| 33 |
+
header{display:flex;align-items:baseline;gap:1rem;margin-bottom:.75rem;
|
| 34 |
+
padding-bottom:.625rem;border-bottom:1px solid #1a1a2e}
|
| 35 |
h1{font-family:'Barlow Condensed',sans-serif;font-weight:800;font-style:italic;
|
| 36 |
+
font-size:1.85rem;color:#fff;letter-spacing:-.01em;line-height:1}
|
| 37 |
+
.meta{color:#64748b;font-size:.72rem;font-family:'SF Mono','Fira Code',monospace}
|
| 38 |
+
.meta b{color:#94a3b8}
|
| 39 |
+
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:.5rem}
|
| 40 |
+
.card{background:#111827;border:1px solid #1e2942;border-top:2px solid var(--c);
|
| 41 |
+
border-radius:8px;padding:.65rem .875rem}
|
| 42 |
+
.card-top{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:.45rem}
|
| 43 |
+
.pid{font-size:.62rem;color:#94a3b8;font-family:'SF Mono','Fira Code',monospace;
|
|
|
|
|
|
|
| 44 |
text-transform:uppercase;letter-spacing:.06em}
|
| 45 |
+
.cn{font-size:.6rem;color:#64748b;font-family:'SF Mono','Fira Code',monospace}
|
| 46 |
+
.rss{font-size:1.5rem;font-weight:700;font-family:'SF Mono','Fira Code',monospace;
|
| 47 |
+
color:var(--c);line-height:1}
|
| 48 |
+
.unit{font-size:.6rem;color:#64748b;font-weight:400;margin-left:.15rem}
|
| 49 |
+
.track{height:3px;background:#1e2942;border-radius:99px;margin-top:.5rem;overflow:hidden}
|
| 50 |
+
.fill{height:100%;border-radius:99px;background:#3b82f6;opacity:.8}
|
| 51 |
+
</style>
|
| 52 |
+
</head><body>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
<header>
|
| 54 |
+
<h1>Prozis Similarity Service</h1>
|
| 55 |
+
<span id="meta" class="meta"></span>
|
| 56 |
</header>
|
| 57 |
+
<div id="grid" class="grid"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
<script>
|
| 59 |
const MAX=__CACHE_MAX__;
|
| 60 |
+
function col(mb){return mb<800?'#4ade80':mb<1000?'#fbbf24':'#f87171'}
|
| 61 |
+
function render(workers){
|
| 62 |
+
const gb=(workers.reduce((s,w)=>s+w.rss_mb,0)/1024).toFixed(1);
|
|
|
|
| 63 |
document.getElementById('meta').innerHTML=
|
| 64 |
+
`<b>${workers.length}</b> workers · <b>${gb} GB</b> RSS · ${new Date().toTimeString().slice(0,8)}`;
|
| 65 |
+
document.getElementById('grid').innerHTML=workers.map(w=>{
|
| 66 |
+
const c=col(w.rss_mb),p=Math.min(100,w.cache_size/MAX*100).toFixed(0);
|
| 67 |
+
return `<div class="card" style="--c:${c}">` +
|
| 68 |
+
`<div class="card-top"><span class="pid">pid ${w.pid}</span><span class="cn">${w.cache_size}/${MAX}</span></div>` +
|
| 69 |
+
`<div class="rss">${w.rss_mb}<span class="unit">MB</span></div>` +
|
| 70 |
+
`<div class="track"><div class="fill" style="width:${p}%"></div></div>` +
|
| 71 |
+
`</div>`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
}).join('');
|
| 73 |
}
|
| 74 |
+
async function refresh(){try{const r=await fetch('/stats');render((await r.json()).workers)}catch(e){}}
|
| 75 |
refresh();setInterval(refresh,5000);
|
| 76 |
</script>
|
| 77 |
</body></html>""").replace("__CACHE_MAX__", str(_CACHE_MAX))
|
|
|
|
| 79 |
|
| 80 |
@app.get("/stats", include_in_schema=False)
|
| 81 |
async def stats_endpoint():
|
| 82 |
+
return {"workers": get_all_memory_stats()}
|
| 83 |
|
| 84 |
|
| 85 |
@app.get("/", include_in_schema=False)
|