Spaces:
Sleeping
Sleeping
| """Knowledge graph API endpoints.""" | |
| import logging | |
| from fastapi import APIRouter, Depends, HTTPException, Query | |
| from fastapi.responses import JSONResponse | |
| from app.core.exceptions import EntityNotFoundError, DatasetError | |
| from app.schemas.knowledge_graph import KnowledgeGraphResponse | |
| from app.services.knowledge_graph_service import KnowledgeGraphService | |
| from app.api.v2.dependencies import get_knowledge_graph_service | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter(prefix="/ai/v2/knowledge-graph", tags=["knowledge-graph"]) | |
| # NOTE: Static-segment routes MUST be declared before dynamic /{lo_id} routes | |
| # so FastAPI doesn't swallow "path" as a lo_id value. | |
| async def get_learning_path_between_los( | |
| start_lo: str, | |
| target_lo: str, | |
| knowledge_graph_service: KnowledgeGraphService = Depends(get_knowledge_graph_service) | |
| ) -> JSONResponse: | |
| """Get learning path between two learning outcomes.""" | |
| try: | |
| path = knowledge_graph_service.get_learning_path(start_lo, target_lo) | |
| return JSONResponse(content={ | |
| "start_lo": start_lo, | |
| "target_lo": target_lo, | |
| "path": path, | |
| "steps": len(path) | |
| }) | |
| except EntityNotFoundError as exc: | |
| logger.warning("Learning path query failed - entity not found: %s", exc) | |
| raise HTTPException(status_code=404, detail=str(exc)) from exc | |
| except Exception as exc: | |
| logger.error("Learning path query failed: %s", exc) | |
| raise HTTPException(status_code=500, detail="Internal server error") from exc | |
| async def get_prerequisites( | |
| lo_id: str, | |
| max_depth: int = Query(default=None, ge=1, le=10, description="Maximum depth to traverse"), | |
| knowledge_graph_service: KnowledgeGraphService = Depends(get_knowledge_graph_service) | |
| ) -> JSONResponse: | |
| """Get prerequisites for a learning outcome.""" | |
| try: | |
| prerequisites = knowledge_graph_service.get_prerequisites(lo_id, max_depth) | |
| return JSONResponse(content={ | |
| "lo_id": lo_id, | |
| "prerequisites": prerequisites, | |
| "count": len(prerequisites) | |
| }) | |
| except EntityNotFoundError as exc: | |
| logger.warning("Prerequisites query failed - entity not found: %s", exc) | |
| raise HTTPException(status_code=404, detail=str(exc)) from exc | |
| except Exception as exc: | |
| logger.error("Prerequisites query failed: %s", exc) | |
| raise HTTPException(status_code=500, detail="Internal server error") from exc | |
| async def get_successors( | |
| lo_id: str, | |
| max_depth: int = Query(default=None, ge=1, le=10, description="Maximum depth to traverse"), | |
| knowledge_graph_service: KnowledgeGraphService = Depends(get_knowledge_graph_service) | |
| ) -> JSONResponse: | |
| """Get successors for a learning outcome.""" | |
| try: | |
| successors = knowledge_graph_service.get_successors(lo_id, max_depth) | |
| return JSONResponse(content={ | |
| "lo_id": lo_id, | |
| "successors": successors, | |
| "count": len(successors) | |
| }) | |
| except EntityNotFoundError as exc: | |
| logger.warning("Successors query failed - entity not found: %s", exc) | |
| raise HTTPException(status_code=404, detail=str(exc)) from exc | |
| except Exception as exc: | |
| logger.error("Successors query failed: %s", exc) | |
| raise HTTPException(status_code=500, detail="Internal server error") from exc | |
| async def get_knowledge_graph( | |
| lo_id: str, | |
| max_depth: int = Query(default=2, ge=1, le=5, description="Maximum depth to traverse"), | |
| knowledge_graph_service: KnowledgeGraphService = Depends(get_knowledge_graph_service) | |
| ) -> KnowledgeGraphResponse: | |
| """Get knowledge graph information for a learning outcome.""" | |
| try: | |
| return knowledge_graph_service.get_knowledge_graph(lo_id, max_depth) | |
| except EntityNotFoundError as exc: | |
| logger.warning("Knowledge graph query failed - entity not found: %s", exc) | |
| raise HTTPException(status_code=404, detail=str(exc)) from exc | |
| except DatasetError as exc: | |
| logger.error("Knowledge graph query failed - dataset error: %s", exc) | |
| raise HTTPException(status_code=503, detail="Knowledge graph service unavailable") from exc | |
| except Exception as exc: | |
| logger.error("Knowledge graph query failed - unexpected error: %s", exc) | |
| raise HTTPException(status_code=500, detail="Internal server error") from exc | |