File size: 2,725 Bytes
345855e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | from fastapi import APIRouter
from fastapi.responses import HTMLResponse, FileResponse
from pathlib import Path
from typing import Dict, List
from core.registry.tasks_registry import TASKS
# =====================================================
# CONFIG
# =====================================================
BASE_DIR = Path(__file__).resolve().parents[2]
UI_DIR = BASE_DIR / "ui"
INDEX_FILE = UI_DIR / "index.html"
# =====================================================
# TASK GROUPING
# =====================================================
def group_tasks() -> Dict[str, List[dict]]:
"""
Converts registry → categorized UI structure.
"""
categories: Dict[str, List[dict]] = {}
for task in TASKS:
if not getattr(task, "enabled", True):
continue
category = getattr(task, "category", "general")
categories.setdefault(category, []).append(
{
"name": task.name,
"description": getattr(task, "description", ""),
}
)
return categories
# =====================================================
# ROUTER BUILDER
# =====================================================
def build_ui_router() -> APIRouter:
"""
Serves UI + dynamic UI metadata.
Endpoints:
/
/ui
/ui/tasks
/ui/health
"""
router = APIRouter(tags=["UI"])
# -------------------------------------------------
# MAIN UI
# -------------------------------------------------
@router.get("/", response_class=HTMLResponse)
async def serve_root():
"""
Serves index.html
"""
if not INDEX_FILE.exists():
return HTMLResponse(
"<h1>Basyx UI Missing</h1>",
status_code=500,
)
return FileResponse(INDEX_FILE)
# -------------------------------------------------
# Explicit UI route
# -------------------------------------------------
@router.get("/ui", response_class=HTMLResponse)
async def serve_ui():
return await serve_root()
# -------------------------------------------------
# UI TASK CATALOG
# -------------------------------------------------
@router.get("/ui/tasks")
async def ui_tasks():
"""
UI fetches this to build sidebar dynamically.
"""
return group_tasks()
# -------------------------------------------------
# HEALTH
# -------------------------------------------------
@router.get("/ui/health")
async def ui_health():
return {
"status": "ok",
"ui": "active",
"tasks": len(TASKS),
}
return router |