Spaces:
Sleeping
Sleeping
File size: 4,551 Bytes
766dbe4 5b6cb96 7a1eda4 766dbe4 7a1eda4 766dbe4 5b6cb96 7a1eda4 5b6cb96 7a1eda4 766dbe4 5b6cb96 766dbe4 2c9c234 5b6cb96 2c9c234 5b6cb96 2c9c234 5b6cb96 2c9c234 766dbe4 5b6cb96 766dbe4 5b6cb96 7a1eda4 5b6cb96 7a1eda4 5b6cb96 7a1eda4 5b6cb96 7a1eda4 5b6cb96 |
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 108 109 110 111 112 113 114 115 116 117 |
import os
import pickle
import pandas as pd
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(title="Student Score Predictor Chatbot")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], allow_credentials=True,
allow_methods=["*"], allow_headers=["*"],
)
templates = Jinja2Templates(directory="templates")
# Load model once at startup
MODEL_PATH = os.getenv('MODEL_PATH', 'student_performance_model.pkl')
try:
with open(MODEL_PATH, 'rb') as f:
model = pickle.load(f)
except Exception as e:
raise RuntimeError(f"Could not load model: {e}")
# Chat‑fields configuration
FIELDS = [
{'name': 'Age', 'type': 'number',
'question': 'What is your age?',
'validation': {'min': 5, 'max': 100}},
{'name': 'Gender', 'type': 'select',
'question': 'What is your gender?',
'options': ['Male', 'Female', 'Other']},
{'name': 'HoursOfStudyPerDay', 'type': 'number',
'question': 'How many hours do you study per day?',
'validation': {'min': 0, 'max': 24}},
{'name': 'SchoolAttendanceRate', 'type': 'number',
'question': 'What is your school attendance rate (%)?',
'validation': {'min': 0, 'max': 100}},
{'name': 'TuitionAccess', 'type': 'select',
'question': 'Do you have access to extra tuition?',
'options': ['Yes', 'No']},
{'name': 'AveragePreviousScores', 'type': 'number',
'question': 'What was your average previous score?',
'validation': {'min': 0, 'max': 100}},
{'name': 'HoursOfSleep', 'type': 'number',
'question': 'How many hours of sleep do you get per night?',
'validation': {'min': 0, 'max': 24}},
{'name': 'BreakfastDaily', 'type': 'select',
'question': 'Do you eat breakfast every day?',
'options': ['Yes', 'No']},
{'name': 'ScreenTimeHours', 'type': 'number',
'question': 'How many hours of screen time per day?',
'validation': {'min': 0, 'max': 24}},
{'name': 'PhysicalActivityHours', 'type': 'number',
'question': 'How many hours of physical activity per day?',
'validation': {'min': 0, 'max': 24}},
{'name': 'PlaysSport', 'type': 'select',
'question': 'Do you play any sports?',
'options': ['Yes', 'No']},
{'name': 'MentalHealthScore', 'type': 'number',
'question': 'Rate your mental health on a scale of 1–10.',
'validation': {'min': 1, 'max': 10}},
{'name': 'ParentalEducationLevel', 'type': 'select',
'question': 'What is your parental education level?',
'options': ['High school', 'Graduate', 'Postgrad']},
{'name': 'HouseholdIncomeLevel', 'type': 'select',
'question': 'What is your household income level?',
'options': ['Low', 'Medium', 'High']},
{'name': 'StudyEnvironmentRating', 'type': 'number',
'question': 'Rate your study environment (1–5).',
'validation': {'min': 1, 'max': 5}},
{'name': 'FriendSupportScore', 'type': 'number',
'question': 'Rate the emotional support from friends (1–10).',
'validation': {'min': 1, 'max': 10}},
{'name': 'ParticipatesInClubs', 'type': 'select',
'question': 'Do you participate in any clubs?',
'options': ['Yes', 'No']},
{'name': 'PartTimeWork', 'type': 'select',
'question': 'Do you do any part‑time work?',
'options': ['Yes', 'No']},
]
@app.get("/", response_class=HTMLResponse)
async def chat_ui(request: Request):
return templates.TemplateResponse("chat.html", {
"request": request,
"fields": FIELDS
})
@app.post("/predict_json")
async def predict_json(payload: dict):
# collect + cast
data = {}
for f in FIELDS:
key = f["name"]
if key not in payload:
raise HTTPException(400, f"Missing field: {key}")
val = payload[key]
if f["type"] == "number":
try:
val = float(val)
except:
raise HTTPException(400, f"{key} must be numeric")
data[key] = val
# validate ranges
for f in FIELDS:
if f["type"] == "number" and "validation" in f:
v = f["validation"]
if not (v["min"] <= data[f["name"]] <= v["max"]):
raise HTTPException(400,
f"{f['name']} must be between {v['min']} and {v['max']}")
df = pd.DataFrame([data])
score = model.predict(df)[0]
return JSONResponse({"predicted": round(float(score), 2)})
|