# ui.py import html, threading from typing import Any, Dict, List from fastapi import APIRouter, HTTPException from fastapi.responses import HTMLResponse, JSONResponse from data import ( get_pages, get_state, ensure_page_loaded, build_all_pages, is_complete, model_id, license_label_and_url, search_models, flatten_models ) router = APIRouter() def _render_table(models: List[Dict[str, Any]]) -> str: rows = [] for m in models: mid = html.escape(model_id(m)) desc = html.escape((m.get("description") or "")[:200]) thumb = m.get("cover_image_url") or m.get("cover_image") or "" vis = html.escape(m.get("visibility") or "") tags = m.get("tags") or m.get("categories") or [] tags_html = " ".join(f"{html.escape(str(t))}" for t in tags[:8]) lic_label, lic_url = license_label_and_url(m) lic_label_h = html.escape(lic_label) lic_html = f"{lic_label_h}" if lic_url else lic_label_h src_links = [] if m.get("github_url"): src_links.append(f"GitHub") if m.get("paper_url"): src_links.append(f"Paper") if lic_url: src_links.append(f"License") sources_html = " | ".join(src_links) run_ct = m.get("run_count") run_html = f"{run_ct:,} runs" if isinstance(run_ct, int) else "" thumb_html = f"" if thumb else "" rows.append( f"" f"{thumb_html}" f"{mid}
{run_html}" f"{desc}" f"{vis}" f"{lic_html}" f"{sources_html}" f"{tags_html}" f"" ) return ( "" "" "" "" "" + "\n".join(rows) + "
ThumbnailID / RunsDescriptionVisibilityLicenseSourcesTags
" ) def _render_pagination(current_page: int) -> str: pages = len(get_pages()) links = [] for i in range(1, pages + 1): if i == current_page: links.append(f"{i}") else: links.append(f"{i}") state = get_state() if state["more"]: links.append(f"") return "
" def _shell(page_index_0: int, html_table: str, *, search_query: str = "") -> str: page_num = page_index_0 + 1 state = get_state() search_disabled = "" if state["complete"] else "disabled" search_opacity = "1.0" if state["complete"] else "0.45" import html as _h return f""" Replicate Catalog — Page {page_num}
Replicate catalog page {page_num} of {state['pages']} known more pages available: {"yes" if state["more"] else "no"} building: {"yes" if state["building"] else "no"} complete: {"yes" if state["complete"] else "no"}
{html_table} {_render_pagination(page_num)}

Commercial stats

Total
Analyzed
Unknown
Commercial-friendly
Copyleft
Non-commercial
No-derivatives

License log

Total models
Known licenses
Unknown licenses
""" @router.get("/page/{n}", response_class=HTMLResponse) def page(n: int): if n < 1: raise HTTPException(status_code=400, detail="Page must be >= 1") idx = n - 1 ensure_page_loaded(idx) pages = get_pages() if idx >= len(pages): raise HTTPException(status_code=404, detail="No more pages.") models = pages[idx]["results"] return HTMLResponse(_shell(idx, _render_table(models))) @router.post("/build_all") def build_all(): if is_complete(): return JSONResponse({"started": False, "reason": "complete"}, status_code=200) threading.Thread(target=build_all_pages, daemon=True).start() return JSONResponse({"started": True}, status_code=202) @router.get("/status") def status(): return JSONResponse(get_state()) @router.get("/search", response_class=HTMLResponse) def search(q: str = ""): idx = 0 base = get_pages()[0]["results"] if get_pages() else [] if is_complete() and q.strip(): results = search_models(q) content = _render_table(results) return HTMLResponse(_shell(idx, content, search_query=q)) else: content = _render_table(base) return HTMLResponse(_shell(idx, content, search_query=q))