AI-powered assignment grading tool — auto-generates rubrics and grades student PDF submissions using Google Gemini.
Project description
Assignment Evaluator
AI-powered assignment grading tool that automatically generates a solution manual & rubric from an assignment PDF, then grades every student submission using Google Gemini vision models. Results are exported to an annotated graded PDF per student and a summary Excel spreadsheet.
Features
- Two-step GUI workflow – pick the assignment PDF, review the auto-generated rubric, then point to the submissions folder and click Start Evaluation.
- Automatic question & mark detection – hybrid regex + Gemini vision extraction.
- Rubric caching – generated rubrics are cached per assignment so you skip re-generation on subsequent runs.
- Graded PDF output – a cover page with per-question scores and feedback is prepended to each student's original PDF.
- Incremental re-runs – already-evaluated submissions are skipped unless you choose to re-evaluate.
- Configurable strictness & feedback style –
lenient / moderate / strictandbrief / balanced / detailed.
Requirements
| Requirement | Notes |
|---|---|
| Python ≥ 3.10 | Standard distribution |
| Poppler | PDF-to-image conversion (see below) |
| Google Gemini API key | Free tier available at https://aistudio.google.com/ |
Poppler installation
Windows – download the pre-built binaries and unzip them. The installer already ships a Release-25.12.0-0 folder next to the package source. If you use a different location, set POPPLER_BIN_PATH:
$env:POPPLER_BIN_PATH = "C:\path\to\poppler\Library\bin"
macOS
brew install poppler
Linux (Debian / Ubuntu)
sudo apt-get install -y poppler-utils
On macOS and Linux, Poppler is usually found automatically on PATH — no extra configuration needed.
Installation
Option A — Standalone executable (Windows, no Python required)
Download AssignmentEvaluator.exe from the Releases page and run it directly — no Python installation needed.
Poppler is still required. Download the Windows binaries from github.com/oschwartz10612/poppler-windows, unzip them, and set the environment variable:
$env:POPPLER_BIN_PATH = "C:\path\to\poppler\Library\bin"
Option B — install from source (recommended for development)
# 1. Clone or copy the project folder
cd assignment-evaluator
# 2. Create and activate a virtual environment (optional but recommended)
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
# 3. Install the package and all dependencies
pip install -e .
Option C — install dependencies only (no package install)
pip install -r requirements.txt
Option D — install from PyPI (once published)
pip install assignment-evaluator
Configuration
Gemini API key
When you launch the app for the first time, a dialog will ask you to enter your Google Gemini API key.
How to get a free key:
- Go to https://aistudio.google.com/app/apikey
- Sign in with your Google account
- Click Create API key
- Copy the key (starts with
AIza…) and paste it into the dialog
The dialog has a "Save key locally for next use" checkbox. When ticked, the key is stored in ~/.assignment_evaluator/api_key.json (permissions set to owner-only on macOS/Linux) so you won't be asked again on subsequent runs.
Security note: The saved file is local to your machine and never transmitted anywhere other than the Google Gemini API. Never commit it to version control.
You can still supply the key via environment variable if you prefer (the env var always takes priority and skips the dialog):
# Linux / macOS
export GEMINI_API_KEY="AIza..."
# Windows PowerShell
$env:GEMINI_API_KEY = "AIza..."
# Windows CMD
set GEMINI_API_KEY=AIza...
Optional environment variables
| Variable | Default | Description |
|---|---|---|
GEMINI_API_KEY |
(GUI prompt) | Skips the key dialog when set |
POPPLER_BIN_PATH |
Auto-detected | Full path to the Poppler bin/ folder |
Usage
Launch the GUI
# If installed as a package
assignment-evaluator
# Or run as a Python module
python -m assignment_evaluator
# Or run the script directly
python assignment_evaluator/app.py
Step-by-step walkthrough
-
Step 1 – Assignment PDF
- Browse to and select the assignment question PDF.
- Choose the Gemini model to use for generating the rubric/solution.
- Click Generate Rubric.
-
Review the rubric
- The app displays the auto-generated solution manual (left) and rubric (right).
- You can Approve and Continue, Regenerate with a different model, or Cancel.
-
Step 2 – Evaluation setup
- Set the submissions folder, output folder, subject name, question count, and per-question marks.
- Adjust strictness, feedback style, and models as needed.
- Click Start Evaluation.
-
Results
- A
*_graded.pdfis written for each student in the output folder. - An
Assignment_Evaluation_Results.xlsxspreadsheet summarises all scores. - Full logs and a JSONL audit trail are written to
evaluation_logs/.
- A
Output structure
Graded_Assignments/
├── Submission_folder_A/
│ ├── student_name_graded.pdf ← annotated PDF with cover page
│ └── ...
├── Assignment_Evaluation_Results.xlsx
evaluation_logs/
└── assignment_eval_YYYYMMDD_HHMMSS/
├── run.log
├── session_config.json
├── solution_manual.txt
├── rubric.json
├── assignment_summary.txt
├── evaluation_audit.jsonl ← one JSON record per submission
└── summary.json
Supported Gemini models
The dropdown in the GUI lists these models (you can also type any valid model name):
| Model | Notes |
|---|---|
gemini-2.5-pro |
Highest accuracy; slower |
gemini-2.5-flash |
Good balance of speed and accuracy |
gemini-2.0-flash |
Default; fast and capable |
gemini-1.5-pro |
Stable, widely available |
gemini-2.0-flash-lite |
Fastest; lower accuracy |
Programmatic API
import os
os.environ["GEMINI_API_KEY"] = "AIza..."
from assignment_evaluator.app import main
main() # launches the full GUI workflow
For headless / server use you can call the lower-level functions directly:
from pathlib import Path
from assignment_evaluator.app import (
_configure_genai,
generate_assignment_materials,
evaluate_single_submission,
setup_logging,
)
_configure_genai()
logger, session_dir = setup_logging("my_run")
config = {
"subject_name": "Physics 101",
"strictness": "moderate",
"feedback_style": "balanced",
"max_marks": {"Q1": 5, "Q2": 5, "Q3": 10},
"expect_handwritten": True,
"evaluator_notes": "",
"page_limit": 40,
"dpi": 150,
"timeout_seconds": 180,
"retry_count": 3,
"solution_model": "gemini-2.0-flash",
"evaluation_model": "gemini-2.0-flash",
}
assignment_pdf = Path("assignment.pdf")
materials = generate_assignment_materials(config, assignment_pdf, session_dir, logger)
result = evaluate_single_submission(
pdf_path=Path("submissions/student_a.pdf"),
submissions_root=Path("submissions"),
output_root=Path("graded"),
config=config,
assignment_materials=materials,
logger=logger,
)
print(result["total_score"], result["grades"])
Development
# Install dev extras
pip install -e ".[dev]"
# Run tests
pytest
# Build a distribution wheel
python -m build
# Upload to PyPI
twine upload dist/*
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file assignment_evaluator-1.0.0.tar.gz.
File metadata
- Download URL: assignment_evaluator-1.0.0.tar.gz
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d620da27840eb0a0d6bf43b56725c8ec5346dae5195ea079802c3c8b91366b78
|
|
| MD5 |
23c3bd6b5f9e30c742bd81911a63ae09
|
|
| BLAKE2b-256 |
6eb95af2b5f24a906a1dbbbcf5f5f6e3c77ba82c89b1b46872e5602351e6f6aa
|
File details
Details for the file assignment_evaluator-1.0.0-py3-none-any.whl.
File metadata
- Download URL: assignment_evaluator-1.0.0-py3-none-any.whl
- Upload date:
- Size: 25.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54b6499e16e2ceb9861860e38e32df4c91fddc26800bdf4d1aa0e4f79eb42e16
|
|
| MD5 |
30aef9897a16a23ee0ad1eff00e79582
|
|
| BLAKE2b-256 |
23e5bc4d6590e0edf2127f5bbda1aeb0959547e49dca2aedd87cc6cd38623ada
|