Selected Work - Engineering

BUC Populi - AI-assisted grading & attendance

An internal academic-operations tool for Bethesda University of California: it pulls student work and class data out of the Populi LMS, drafts essay grades with Claude, and runs a weekly attendance audit that flags F1 international students at immigration-compliance risk - all from a lean Python codebase with a Streamlit dashboard, a handful of CLI scripts, and cron.

GRADING ENGINE· claude-sonnet-4
live
essay_4821.docx
Thesis
18/20
Evidence
16/20
Structure
20/20
Grammar
17/20
86/100
confidence: high
no plagiarismon-topiccitations ✓

DRAFT · pending_review

awaiting human approval · never auto-pushed

Role

Solo Engineer

Stack

Python 3.12 · Populi API v2 · Anthropic Claude · Streamlit · SMTP · cron

Links

GitHub

01Overview

BUC Populi automates two time-consuming jobs at a small university: grading written work and keeping attendance records defensible. It talks to Populi, the LMS, over its REST API, uses Claude to draft essay grades against a rubric, and emails professors when attendance needs attention. There is no database, since Populi is the system of record and everything else is a script, a dashboard, or a cron job. The tool is used by about 40 professors and has cut grading time by roughly 60 percent.

AUTOMATION· weekly cron pipeline
live

cron

mon 07:00

fetch

Populi API

grade

Claude

audit

SEVIS

email

SMTP

generate_weekly_report.py
$ cron · mon 07:00
→ fetch_populi  ✓ 12 courses · 326 submissions
→ grade (claude)  ✓ 48 drafts · pending_review
→ audit (sevis)  ⚠ 3 SEVIS flags raised
→ email (smtp)  ✓ 40 professors notified
done in 4.2s
submissions326
graded · draft48
SEVIS flags3
~60%grading time saved

02What I built

  • Grading engine - (grader/engine.py) - builds a structured prompt from a JSON rubric, sends the extracted essay to Claude (claude-sonnet-4-20250514), and returns per-criterion scores, student-facing feedback, flags (plagiarism / off-topic / missing citations), and a confidence level - defensively parsing the model's JSON and never auto-submitting a grade.

  • Attendance-compliance auditor - (populi/attendance_audit.py) - derives online vs. in-person weeks, computes the term week number, detects late submissions, and runs a decision matrix that flags exactly which students need an attendance correction or pose a compliance risk.

  • Streamlit dashboard - (dashboard.py) - a zero-frontend internal web UI with four tabs: Master Report (multi-course audit with a course picker and inline email/schedule controls), Submission & Attendance, Grade Assignments, and Attendance Audit.

  • Email-alert pipeline - (email_alerts.py) - composes per-professor and admin-summary emails from the weekly report JSON and sends them over SMTP.

  • Cron automation - (cron_setup.sh) - a hands-off weekly cadence: generate the report Monday 7:00, email professors 7:30, refresh daily Tue–Fri 8:00.

  • CLI & export utilities - run_grading.py, list_courses.py, export_data.py, submission_report.py, and generate_weekly_report.py for discovery, batch grading, reporting, and CSV/JSON export.

03Architecture

CLI Scripts

run_grading · list_courses · export

Streamlit Dashboard

dashboard.py · 4 tabs

Populi Client

REST client · 45 req/min · pagination · caching

Grading

Claude Sonnet 4 · JSON rubric

Audit

Week logic · SEVIS flags

Email

SMTP · weekly alerts

Data

data/ JSON / CSV · gitignored

A single Populi API client is the one door to the LMS, and the dashboard and every CLI script go through it. From there the work fans out to the Claude API for grading, SMTP for alerts, and a local data directory for draft grades and reports. There is no database: Populi holds the canonical data and the tool re-derives what it needs on each run.

04Technical challenges

Attendance derived from source

Problem
In hybrid sections, whether a week was online or in person changes what present means, and guessing from a fixed schedule breaks the moment a week deviates.
Approach
I read it from Populi instead of assuming it. One function derives online versus in-person from each meeting's is_online flag, another anchors the term week number, and assignment cutoffs add a day so a late Sunday submission still lands in the right week.
Result
Week classification stays correct as real schedules drift, with no per-course hand-tuning.

AI grading behind a human gate

Problem
An LLM grade that flows straight into a student's record is unacceptable both academically and ethically.
Approach
The grader builds a rubric-driven prompt that returns strict JSON for scores, feedback, flags, and confidence, parses it defensively when the model adds preamble, skips empty or too-short submissions, and writes every result as a draft at pending_review.
Result
Claude does the first pass at scale, and a human stays the system of record for every grade.

Staying under the rate limit

Problem
Populi enforces a request-rate limit, and a naive multi-course audit blows straight through it.
Approach
The client self-throttles to 45 requests per minute, under the 50 limit, handles pagination transparently, and caches person and term lookups so repeated audits do not re-fetch the same records.
Result
Large multi-course reports run without tripping the limit or hammering the LMS.

Cron pipeline that won't double-fire

Problem
The whole point is that it runs unattended, but retries, overlapping runs, or a manual re-run could double-grade a submission or send the same alert twice.
Approach
I made each stage idempotent and keyed on what it has already processed, so a re-run reconciles instead of duplicating, and graded results still land as drafts behind the human gate.
Result
The weekly cadence runs itself safely, with no duplicate grades or repeated alerts.

05Stack & why

Python for the integration glue, Populi as the system of record, Claude behind a human gate.

Python 3.12Populi API v2requestsAnthropic Claudepdfplumberpython-docxStreamlitpandasrichpython-dotenvsmtplibcron

06Outcomes

StatusIn use by BUC staff (internal tool)
~40Professors using the tool
~60%Reduction in grading time vs. manual marking
AttendanceManual weekly attendance-checking effort largely automated
~3,300Lines of Python (single author)
4Streamlit dashboard tabs (Master Report · Submission · Grading · Audit)
6CLI scripts (discovery · grading · reporting · export)
12Populi API v2 endpoints integrated, behind one throttled client
Claude Sonnet 4Rubric-driven essay grading with structured-JSON output
Human-in-the-loopNo grade ever auto-pushed - all drafts held at pending_review
ComplianceAutomated weekly F1 / SEVIS attendance flagging + email alerts
No DB / no APINo database or custom API backend - Populi is the system of record; the tool is CLI scripts, a Streamlit dashboard, and cron on a single host