File size: 3,549 Bytes
c045254
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Adaptive learning path API endpoints."""

import logging
from fastapi import APIRouter, Depends, HTTPException, Query

from app.core.exceptions import EntityNotFoundError, DatasetError
from app.schemas.learning_path import LearningPathRequest, LearningPathResponse
from app.services.adaptive_learning_path_service import AdaptiveLearningPathService
from app.api.v2.dependencies import get_adaptive_learning_path_service

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/ai/v2/learning-path", tags=["learning-path"])


@router.get(
    "/{student_id}",
    response_model=LearningPathResponse,
    summary="Generate adaptive learning path",
    description="Generate a personalized learning path for a student to reach a target learning outcome"
)
async def generate_learning_path(
    student_id: str,
    target_lo_id: str = Query(..., description="Target learning outcome ID"),
    max_steps: int = Query(default=10, ge=1, le=20, description="Maximum number of steps in path"),
    include_mastered: bool = Query(default=False, description="Include already mastered LOs for review"),
    difficulty_preference: str = Query(default="adaptive", description="Difficulty preference: easy, medium, hard, adaptive"),
    learning_path_service: AdaptiveLearningPathService = Depends(get_adaptive_learning_path_service)
) -> LearningPathResponse:
    """Generate an adaptive learning path for a student."""
    try:
        request = LearningPathRequest(
            student_id=student_id,
            target_lo_id=target_lo_id,
            max_steps=max_steps,
            include_mastered=include_mastered,
            difficulty_preference=difficulty_preference
        )
        
        return learning_path_service.generate_learning_path(request)
        
    except EntityNotFoundError as exc:
        logger.warning("Learning path generation failed - entity not found: %s", exc)
        raise HTTPException(status_code=404, detail=str(exc)) from exc
    except DatasetError as exc:
        logger.error("Learning path generation failed - dataset error: %s", exc)
        raise HTTPException(status_code=503, detail="Learning path service unavailable") from exc
    except Exception as exc:
        logger.error("Learning path generation failed - unexpected error: %s", exc)
        raise HTTPException(status_code=500, detail="Internal server error") from exc


@router.post(
    "/",
    response_model=LearningPathResponse,
    summary="Generate adaptive learning path (POST)",
    description="Generate a personalized learning path using POST request body"
)
async def generate_learning_path_post(
    request: LearningPathRequest,
    learning_path_service: AdaptiveLearningPathService = Depends(get_adaptive_learning_path_service)
) -> LearningPathResponse:
    """Generate an adaptive learning path for a student using POST."""
    try:
        return learning_path_service.generate_learning_path(request)
        
    except EntityNotFoundError as exc:
        logger.warning("Learning path generation failed - entity not found: %s", exc)
        raise HTTPException(status_code=404, detail=str(exc)) from exc
    except DatasetError as exc:
        logger.error("Learning path generation failed - dataset error: %s", exc)
        raise HTTPException(status_code=503, detail="Learning path service unavailable") from exc
    except Exception as exc:
        logger.error("Learning path generation failed - unexpected error: %s", exc)
        raise HTTPException(status_code=500, detail="Internal server error") from exc