"""Gradio Server assembly. Builds the ``gradio.Server`` (FastAPI-style API through Gradio), registers the backend endpoints, and serves the **custom HTML/JS frontend** at the site root. The frontend (``src/frontend/index.html`` + ``static/``) is a hand-authored single-page app — onboarding wizard → salary dashboard → contextual rights chat — that calls the registered ``@app.api`` endpoints (``/dashboard``, ``/chat``, ``/parse_lonstatistik``) via the Gradio JS client. This is the "off-brand" custom UI; Gradio's own theming is not used here. See: https://huggingface.co/blog/introducing-gradio-server """ from __future__ import annotations from pathlib import Path from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from gradio import Server from .api.endpoints import register # src/frontend/{index.html, static/} FRONTEND = Path(__file__).resolve().parents[1] / "frontend" INDEX_HTML = FRONTEND / "index.html" STATIC_DIR = FRONTEND / "static" def build_server() -> Server: """Create the configured Gradio Server with the custom frontend at ``/``.""" app = Server() # Backend API endpoints (queue-managed, gradio_client / JS-client compatible). register(app) # Serve the custom single-page frontend. The Gradio JS client connects to the # same origin and calls the registered API endpoints by name. app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static") @app.get("/") def _index() -> FileResponse: # noqa: D401 — serves the SPA shell return FileResponse(str(INDEX_HTML)) return app