FastAPI backend for student performance prediction and KPI dashboard analytics.
This API provides two main functionalities:
- Machine Learning Predictions: Predict student final results and dropout probability
- KPI Dashboard: OLAP queries for student performance analytics
- Framework: FastAPI
- Database: MySQL with PyMySQL
- ML: scikit-learn (RandomForest models)
- Testing: pytest, requests
- Logging: loguru
src/
├── api/ # API endpoints
│ ├── router.py # Prediction endpoints
│ └── kpi_router.py # KPI dashboard endpoints
├── services/ # Business logic
│ ├── model_service.py # ML model loading
│ ├── encoder_service.py # Feature encoding
│ ├── predictor_service.py # Prediction logic
│ └── kpi_service.py # KPI queries
├── schemas/ # Request/response models
│ ├── requests/ # Pydantic request schemas
│ ├── responses/ # Pydantic response schemas
│ └── types/ # TypedDict definitions
├── core/ # Core utilities
│ ├── database.py # Database connection
│ └── logging.py # Logger setup
├── config/ # Configuration
│ └── settings.py # App settings
└── app.py # FastAPI application
- Python 3.12+
- MySQL Server
- Virtual environment (recommended)
- Clone the repository:
git clone <repository-url>
cd capstone-backend- Create and activate virtual environment:
python -m venv .venv
# Windows
.\.venv\Scripts\Activate.ps1
# Linux/Mac
source .venv/bin/activate- Install dependencies:
pip install -r requirements.txt- Configure database in
src/config/settings.py:
DB_CONFIG = {
"host": "localhost",
"port": 3308,
"user": "root",
"password": "",
"database": "capstone_kpi"
}- Place trained models in
src/ml/directory:
dropout_model.pklfinal_grade_model.pkllabel_encoder_dropout.pkllabel_encoder_finalgrade.pkl
Start the server:
python src/app.pyServer will be available at: http://localhost:8000
API Documentation:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc - OpenAPI JSON:
http://localhost:8000/openapi.json
GET / - Root endpoint
GET /health - Health status with model readiness
POST /api/predict/final-result - Predict student Final Result
{
"gender": "M",
"age_band": "35-55",
"studied_credits": 120,
"num_of_prev_attempts": 0,
"total_clicks": 1500,
"avg_assessment_score": 75.5
}POST /api/predict/dropout - Predict dropout probability
{
"gender": "F",
"age_band": "0-35",
"studied_credits": 60,
"num_of_prev_attempts": 0,
"total_clicks": 1500,
"avg_assessment_score": 75.5
}GET /api/models/status - Check model loading status
GET /api/kpi/overview - Complete dashboard overview
GET /api/kpi/student-performance - Student performance summary
GET /api/kpi/module-statistics - Module-level statistics
GET /api/kpi/vle-engagement - VLE engagement metrics
GET /api/kpi/assessment-summary - Assessment score summary
Both models use the same 6 features:
gender: "M" or "F"age_band: "0-35", "35-55", or "55<="studied_credits: Integernum_of_prev_attempts: Integertotal_clicks: Integeravg_assessment_score: Float
- Algorithm: RandomForestClassifier
- Training: scikit-learn 1.1.3
- Runtime: scikit-learn 1.5.2 (compatible)
Final Result Model:
[gender, age_band, studied_credits, num_of_prev_attempts, total_clicks, avg_assessment_score]Dropout Model:
[avg_assessment_score, total_clicks, studied_credits, num_of_prev_attempts, gender, age_band]Required tables in capstone_kpi database:
studentinfo- Student demographicsstudentassessment- Assessment scoresassessments- Assessment metadatastudentvle- VLE interaction logsvle- VLE resourcescourses- Course informationstudentregistration- Registration data
pytestEnsure server is running, then:
python src/tests/http_request_test.pypython src/tests/debug_encoders.py
python src/tests/debug_dropout.py- ModelService: Loads pickle files at startup
- EncoderService: Encodes categorical features using LabelEncoders
- PredictorService: Makes predictions with encoded features
- KPIService: Executes OLAP queries without ORM
Services are initialized in FastAPI lifespan and stored in app.state:
app.state.model_service
app.state.encoder_service
app.state.predictor_service
app.state.kpi_serviceAll endpoints return consistent error responses:
{
"success": false,
"error": "Error message",
"detail": "Additional details"
}CORS is enabled for all origins (development mode):
allow_origins=["*"]
allow_methods=["*"]
allow_headers=["*"]For production, restrict to specific origins.
python download_openapi.pycurl http://localhost:8000/openapi.json -o openapi.jsonNavigate to http://localhost:8000/openapi.json and save the file.
- Check file paths in
src/services/model_service.py - Verify pickle files exist in
src/ml/ - Check scikit-learn version compatibility
- Verify MySQL is running
- Check port and credentials in
src/config/settings.py - Ensure database
capstone_kpiexists
- Endpoints are at
/api/kpi/*not/kpi/* - Check router prefix configuration
- Ensure numpy types are converted to Python natives
- Check
int()wrapping in encoder/predictor services