| from fastapi import APIRouter |
| from fastapi.responses import JSONResponse |
| from typing import Dict, Any, List |
|
|
| from core.registry.tasks_registry import TASKS |
|
|
|
|
| |
| |
| |
|
|
| def _serialize_task(task) -> Dict[str, Any]: |
| """ |
| Convert TaskDefinition → API-safe metadata. |
| Must NOT import task modules. |
| """ |
|
|
| return { |
| "name": getattr(task, "name", None), |
| "description": getattr(task, "description", ""), |
| "category": getattr(task, "category", "general"), |
| "module": getattr(task, "module", None), |
| "callable": getattr(task, "callable_name", "run"), |
| "async": getattr(task, "async_task", False), |
| "enabled": getattr(task, "enabled", True), |
| } |
|
|
|
|
| def _group_tasks(tasks: List[Any]) -> Dict[str, List[Dict[str, Any]]]: |
| """ |
| Groups tasks by category for UI rendering. |
| """ |
|
|
| grouped: Dict[str, List[Dict[str, Any]]] = {} |
|
|
| for task in tasks: |
| category = getattr(task, "category", "general") |
| grouped.setdefault(category, []).append(_serialize_task(task)) |
|
|
| return grouped |
|
|
|
|
| |
| |
| |
|
|
| def build_docs_router() -> APIRouter: |
| """ |
| Builds dynamic documentation endpoints. |
| |
| Provides: |
| /docs/tasks → flat task list |
| /docs/catalog → grouped tasks |
| /docs/health → docs status |
| """ |
|
|
| router = APIRouter( |
| prefix="/docs", |
| tags=["Documentation"], |
| ) |
|
|
| |
| |
| |
| @router.get("/tasks") |
| async def list_tasks(): |
| return JSONResponse( |
| [_serialize_task(task) for task in TASKS] |
| ) |
|
|
| |
| |
| |
| @router.get("/catalog") |
| async def task_catalog(): |
| return JSONResponse(_group_tasks(TASKS)) |
|
|
| |
| |
| |
| @router.get("/health") |
| async def docs_health(): |
| return { |
| "status": "ok", |
| "service": "docs", |
| "tasks_registered": len(TASKS), |
| } |
|
|
| return router |