feat: enrich list API responses with CivitAI stats from local DB

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-15 14:34:51 +01:00
parent c1e124bcc8
commit c3cd35add7
3 changed files with 113 additions and 4 deletions
+68 -3
View File
@@ -11,13 +11,21 @@ to the local ComfyUI frontend (the remote instance has no connected browsers).
from __future__ import annotations
import asyncio
import json
import logging
import aiohttp
from aiohttp import web, WSMsgType
from .config import remote_config
from .remote_client import RemoteLoraClient
try:
from .config import remote_config
except ImportError:
from config import remote_config # type: ignore[no-redef]
try:
from .remote_client import RemoteLoraClient
except ImportError:
from remote_client import RemoteLoraClient # type: ignore[no-redef]
logger = logging.getLogger(__name__)
@@ -178,6 +186,53 @@ _SEND_SYNC_HANDLERS = {
"/api/lm/register-nodes": _handle_register_nodes,
}
# ---------------------------------------------------------------------------
# Stats enrichment
# ---------------------------------------------------------------------------
_stats_db = None
def _get_stats_db():
"""Lazy-initialize the stats database."""
global _stats_db
if _stats_db is None:
try:
from .stats_db import StatsDB as _StatsDBClass
except ImportError:
from stats_db import StatsDB as _StatsDBClass
_stats_db = _StatsDBClass()
_stats_db.init()
return _stats_db
def _enrich_list_response(response_data: dict, db=None) -> dict:
"""Merge stats from the local DB into a list API response."""
items = response_data.get("items", [])
if not items:
return response_data
if db is None:
db = _get_stats_db()
hashes = [item["sha256"] for item in items if item.get("sha256")]
if not hashes:
return response_data
stats_map = db.get_by_hashes(hashes)
for item in items:
sha = item.get("sha256")
if sha and sha in stats_map:
s = stats_map[sha]
item["download_count"] = s["download_count"]
item["rating"] = s["rating"]
item["rating_count"] = s["rating_count"]
item["thumbs_up_count"] = s["thumbs_up_count"]
return response_data
# Shared HTTP session for proxied requests (connection pooling)
_proxy_session: aiohttp.ClientSession | None = None
@@ -332,7 +387,17 @@ async def lm_remote_proxy_middleware(request: web.Request, handler):
# Regular proxy routes
if _should_proxy(path):
return await _proxy_http(request)
response = await _proxy_http(request)
# Enrich model list responses with stats from local DB
if (path.endswith("/list") and path.startswith("/api/lm/")
and response.status == 200):
try:
body = json.loads(response.body)
enriched = _enrich_list_response(body)
return web.json_response(enriched)
except Exception:
pass # Return original response on any error
return response
# Not a LoRA Manager route — fall through
return await handler(request)