AI-powered exam parsing, grading, analytics, and personalized practice for teachers.
Turn scanned physics papers into structured questions, grade student answers, analyze learning gaps, manage a reusable problem bank, and generate targeted practice papers from one web workspace.
![]() |
![]() |
![]() |
![]() |
EduAI is a full-stack teaching assistant for paper-based assessment workflows. Teachers can upload PDF exam papers or student submissions, let a vision model extract the questions, review and edit the structured result, grade each question with AI assistance, and then turn the results into actionable learning reports.
The app is designed around a complete teacher workflow: manage classes and students, parse papers, inspect answers beside the original PDF, build a searchable question bank, identify weak physics domains, and generate personalized practice papers for targeted remediation.
- PDF-to-question pipeline: renders PDF pages, runs a sliding-window vision extraction flow, and stores structured questions for review.
- Side-by-side grading workspace: keeps the original paper preview and extracted question cards in one screen, with per-question grading, editing, re-analysis, and import actions.
- Learning analytics: summarizes score, accuracy, domain mastery, historical trends, and AI-generated study suggestions.
- Problem bank: stores reusable questions in SQLite, supports filtering by domain, type, difficulty, score, and semantic similarity search with embeddings.
- Personalized generator: selects problems from the bank based on weak domains and uses an OpenAI-compatible model to adapt them into a targeted practice paper.
- Teacher management: provides account login, API-key settings, class CRUD, student CRUD, assignment status, and student-specific analysis entry points.
- Modern web UI: built with React, Vite, Tailwind CSS, DaisyUI, PDF preview, Markdown, KaTeX, and Recharts.
| Area | Stack |
|---|---|
| Frontend | React 19, Vite 6, React Router 7, Tailwind CSS 4, DaisyUI 5 |
| Visualization | Recharts, pdfjs-dist, react-markdown, remark-gfm, KaTeX |
| Backend | Python 3.13+, FastAPI, Uvicorn, PyMuPDF, python-dotenv |
| AI | OpenAI-compatible vision and chat APIs, embedding models |
| Storage | SQLite databases under OUTPUT_DIR for auth, classes, jobs, and problems |
| Tooling | uv, npm, unittest |
- Create classes and students from the teacher dashboard.
- Upload exam PDFs or answer files for a selected student or assignment.
- Parse papers with a vision model and stream extraction progress in the browser.
- Review, edit, grade, and re-analyze each question while keeping the PDF visible.
- Generate reports to find weak domains and knowledge points.
- Import valuable questions into the problem bank.
- Generate custom practice papers from the bank and export them as PDFs.
- Python
>= 3.13 - Node.js
>= 20 - uv recommended for Python dependency management
- An OpenAI-compatible API endpoint for vision, chat, and embeddings
git clone <your-repository-url>
cd eduai
uv sync
cd frontend
npm installCreate a .env file in the repository root:
OUTPUT_DIR=output
VISION_API_KEY=sk-...
VISION_BASE_URL=https://api.openai.com/v1
VISION_MODEL=gpt-4o
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o
EMBEDDING_MODEL=text-embedding-3-small
GRADING_API_KEY=
GRADING_BASE_URL=
GRADING_MODEL=You can also configure model credentials per user from the in-app settings page. This is useful when multiple teachers share the same deployment but need separate API keys.
Run from the repository root:
uv run uvicorn backend.app:app --reload --host 0.0.0.0 --port 8000Health check:
http://127.0.0.1:8000/api/health
cd frontend
npm run devThe Vite dev server proxies /api requests to http://127.0.0.1:8000 by default. To change that target:
VITE_API_PROXY_TARGET=http://127.0.0.1:8000 npm run devcd frontend
npm run build
npm run preview| Command | Description |
|---|---|
uv run uvicorn backend.app:app --reload |
Start the FastAPI backend |
cd frontend && npm run dev |
Start the frontend dev server |
cd frontend && npm run build |
Build frontend static assets |
python -m unittest test_backend_api.py |
Run backend API tests with mocked pipeline behavior |
Most backend routes are served under /api.
| Module | Routes |
|---|---|
| Auth | POST /api/auth/register, POST /api/auth/login, GET /api/auth/me, PUT /api/auth/settings |
| Classes | GET /api/classes, POST /api/classes, GET /api/classes/{class_id}/students |
| Jobs | POST /api/jobs, GET /api/jobs/{job_id}, GET /api/jobs/{job_id}/extract/stream |
| Grading | POST /api/jobs/{job_id}/grade/{question_index}, GET /api/jobs/{job_id}/grade/{question_index}/stream |
| Reports | GET /api/report/{job_id}, POST /api/report/{job_id}/analyze |
| Problem Bank | GET /api/problems, POST /api/problems/search, POST /api/problems/import/{job_id} |
| Generator | POST /api/generate, GET /api/generate/{gen_id}/stream, GET /api/generate/{gen_id}/result |
See backend/app.py for the complete route definitions.
eduai/
├── backend/ FastAPI app, auth, job store, reports, problem bank, generator
├── frontend/ React single-page application
├── problem_analyzer/ Vision extraction and grading agents
├── doc/ Product screenshots used in this README
├── output/ Runtime data directory, created locally when the app runs
├── pdf_renderer.py PDF-to-image renderer
├── pyproject.toml Python project metadata and dependencies
└── test_backend_api.py Backend API test coverage
By default, EduAI writes uploads, generated page images, auth data, job records, and the problem bank under OUTPUT_DIR, which defaults to output/. For production deployments, mount this directory as persistent storage or set OUTPUT_DIR to an absolute path.
EduAI is released under the MIT License.




