"""Get list of available KS2 performance metrics for primary schools."""
df=load_school_data()
# Define KS2 metric metadata organized by category
metric_info={
# Expected Standard
"rwm_expected_pct":{"name":"RWM Combined %","description":"% meeting expected standard in reading, writing and maths","type":"percentage","category":"expected"},
"reading_expected_pct":{"name":"Reading Expected %","description":"% meeting expected standard in reading","type":"percentage","category":"expected"},
"writing_expected_pct":{"name":"Writing Expected %","description":"% meeting expected standard in writing","type":"percentage","category":"expected"},
"maths_expected_pct":{"name":"Maths Expected %","description":"% meeting expected standard in maths","type":"percentage","category":"expected"},
"gps_expected_pct":{"name":"GPS Expected %","description":"% meeting expected standard in grammar, punctuation & spelling","type":"percentage","category":"expected"},
"science_expected_pct":{"name":"Science Expected %","description":"% meeting expected standard in science","type":"percentage","category":"expected"},
# Higher Standard
"rwm_high_pct":{"name":"RWM Combined Higher %","description":"% achieving higher standard in RWM combined","type":"percentage","category":"higher"},
"reading_high_pct":{"name":"Reading Higher %","description":"% achieving higher standard in reading","type":"percentage","category":"higher"},
"writing_high_pct":{"name":"Writing Higher %","description":"% achieving greater depth in writing","type":"percentage","category":"higher"},
"maths_high_pct":{"name":"Maths Higher %","description":"% achieving higher standard in maths","type":"percentage","category":"higher"},
"gps_high_pct":{"name":"GPS Higher %","description":"% achieving higher standard in GPS","type":"percentage","category":"higher"},
# Progress Scores
"reading_progress":{"name":"Reading Progress","description":"Progress in reading from KS1 to KS2","type":"score","category":"progress"},
"writing_progress":{"name":"Writing Progress","description":"Progress in writing from KS1 to KS2","type":"score","category":"progress"},
"maths_progress":{"name":"Maths Progress","description":"Progress in maths from KS1 to KS2","type":"score","category":"progress"},
# Average Scores
"reading_avg_score":{"name":"Reading Avg Score","description":"Average scaled score in reading","type":"score","category":"average"},
"maths_avg_score":{"name":"Maths Avg Score","description":"Average scaled score in maths","type":"score","category":"average"},
"gps_avg_score":{"name":"GPS Avg Score","description":"Average scaled score in GPS","type":"score","category":"average"},
# Gender Performance
"rwm_expected_boys_pct":{"name":"RWM Expected % (Boys)","description":"% of boys meeting expected standard","type":"percentage","category":"gender"},
"rwm_expected_girls_pct":{"name":"RWM Expected % (Girls)","description":"% of girls meeting expected standard","type":"percentage","category":"gender"},
"rwm_high_boys_pct":{"name":"RWM Higher % (Boys)","description":"% of boys at higher standard","type":"percentage","category":"gender"},
"rwm_high_girls_pct":{"name":"RWM Higher % (Girls)","description":"% of girls at higher standard","type":"percentage","category":"gender"},
# Disadvantaged Performance
"rwm_expected_disadvantaged_pct":{"name":"RWM Expected % (Disadvantaged)","description":"% of disadvantaged pupils meeting expected","type":"percentage","category":"equity"},
"rwm_expected_non_disadvantaged_pct":{"name":"RWM Expected % (Non-Disadvantaged)","description":"% of non-disadvantaged pupils meeting expected","type":"percentage","category":"equity"},
"disadvantaged_gap":{"name":"Disadvantaged Gap","description":"Gap between disadvantaged and national non-disadvantaged","type":"score","category":"equity"},
# School Context
"disadvantaged_pct":{"name":"% Disadvantaged Pupils","description":"% of pupils eligible for free school meals or looked after","type":"percentage","category":"context"},
"eal_pct":{"name":"% EAL Pupils","description":"% of pupils with English as additional language","type":"percentage","category":"context"},
"sen_support_pct":{"name":"% SEN Support","description":"% of pupils with SEN support","type":"percentage","category":"context"},
"stability_pct":{"name":"% Pupil Stability","description":"% of non-mobile pupils (stayed at school)","type":"percentage","category":"context"},
# 3-Year Averages
"rwm_expected_3yr_pct":{"name":"RWM Expected % (3-Year Avg)","description":"3-year average % meeting expected","type":"percentage","category":"trends"},
"reading_avg_3yr":{"name":"Reading Score (3-Year Avg)","description":"3-year average reading score","type":"score","category":"trends"},
"maths_avg_3yr":{"name":"Maths Score (3-Year Avg)","description":"3-year average maths score","type":"score","category":"trends"},
}
available=[]
forcol,infoinmetric_info.items():
ifdf.emptyorcolindf.columns:
available.append({"key":col,**info})
return{"metrics":available}
@app.get("/api/rankings")
asyncdefget_rankings(
metric:str=Query("rwm_expected_pct",description="KS2 metric to rank by"),
year:Optional[int]=Query(None,description="Specific year (defaults to most recent)"),
limit:int=Query(20,description="Number of schools to return"),
):
"""Get primary school rankings by a specific KS2 metric."""
df=load_school_data()
ifdf.empty:
return{"metric":metric,"year":None,"rankings":[]}
ifmetricnotindf.columns:
raiseHTTPException(status_code=400,detail=f"Metric '{metric}' not available")
# Filter by year
ifyear:
df=df[df["year"]==year]
else:
# Use most recent year
max_year=df["year"].max()
df=df[df["year"]==max_year]
# Sort and rank (exclude rows with no data for this metric)
df=df.dropna(subset=[metric])
# For progress scores, higher is better. For percentages, higher is also better.