A comprehensive grade synchronization and management system that integrates with assessment platforms (Gradescope, PrairieLearn, iClicker) to automate gradebook updates and facilitate post-semester submissions.
- Overview
- Architecture
- Features
- Quick Start
- Installation
- Configuration
- Usage
- API Documentation
- Deployment
- Development
- Troubleshooting
- Contributing
- License
GradeSync is a backend microservice designed for educational institutions to:
- Automate grade synchronization from multiple assessment platforms
- Store grades in PostgreSQL for reliable persistence and querying
- Provide REST API endpoints for frontend applications and third-party integrations
- Generate Google Sheets summaries for instructor convenience
- Support post-semester workflows allowing students to submit after term ends
β
Automated Updates - No manual CSV downloads or spreadsheet updates
β
Multi-Platform Support - Gradescope, PrairieLearn, iClicker integration
β
Database-Backed - Reliable PostgreSQL storage with full audit trails
β
RESTful API - Easy integration with dashboards, mobile apps, and LMS
β
Flexible Deployment - Docker containers for easy scaling
βββββββββββββββ
β Gradescope ββββ
βββββββββββββββ β
βββββββββββββββ β
βPrairieLearn ββββ€ β Download CSVs
βββββββββββββββ β
βββββββββββββββ β
β iClicker ββββ
βββββββββββββββ
β
β
ββββββββββββββββββββββββββββββββ
β Sync Scripts (Cron Jobs) β
β - gradescope/gradescope_to β
β _spreadsheet.py β
β - prairieLearn/pl_to_ β
β spreadsheet.py β
βββββββββββββ¬βββββββββββββββββββ
β
β β‘ Ingest via Core Module
β
βββββββββββββββββββββββββββββββ
β Core Database Module β
β - ingest.py (CSVβDB) β
β - summary_from_db.py β
β - models.py (ORM) β
βββββββββββββ¬ββββββββββββββββββ
β
β β’ Store
β
βββββββββββββββββββββββββββββββ
β PostgreSQL Database β
β - courses β
β - assignments β
β - students β
β - submissions β
βββββββββββββ¬ββββββββββββββββββ
β
βββββββββββββββ
β β£ Query β β€ Generate
β β
ββββββββββββ ββββββββββββββ
β REST API β β Google β
β(FastAPI) β β Sheets β
βββββββ¬βββββ β Summary β
β ββββββββββββββ
β β₯ Serve
β
βββββββββββββββββββββββββββ
β Client Applications β
β - Web Dashboard β
β - Mobile Apps β
β - Canvas/LMS β
β - Slack Bots β
βββββββββββββββββββββββββββ
GradeSync/
βββ π core/ # Database operations (shared)
β βββ db.py # Database connection
β βββ models.py # SQLAlchemy ORM models
β βββ ingest.py # CSV β Database ingestion
β βββ summary_from_db.py # Database β Summary generation
β
βββ π api/ # REST API service (FastAPI)
β βββ app.py # API endpoints
β βββ gradescopeClient.py # Gradescope API client
β βββ utils.py # Utility functions
β βββ config_loader.py # Configuration loader
β
βββ π gradescope/ # Gradescope sync scripts
β βββ gradescope_to_spreadsheet.py # Main sync script
β βββ dueDate.py # Due date extraction
β βββ fill_summary_emails.py # Email population utility
β
βββ π prairieLearn/ # PrairieLearn sync scripts
β βββ pl_to_spreadsheet.py # PL sync script
β
βββ π iclicker/ # iClicker sync scripts
β βββ iclicker_to_spreadsheet.py # iClicker sync script
β
βββ π config/ # Centralized configuration
β βββ courses.json # Course settings
β
βββ π scripts/ # Utility scripts
βββ backfill_grades.py # Historical data import
βββ generate_summary_sheets.py
βββ update_categories.py
-
Multi-Platform Integration
- Gradescope (primary)
- PrairieLearn
- iClicker
-
Database-First Architecture
- PostgreSQL for reliable storage
- Full audit trail with CSV backups
- Automatic assignment categorization
-
RESTful API
- Get grades for individual assignments
- Fetch all assignments for a course
- Query student performance
- PrairieLearn integration endpoints
-
Google Sheets Integration
- Auto-generate summary sheets
- Formula-free (DB-backed) for reliability
- Clickable assignment index
-
Automation Ready
- Docker containerization
- Cron job compatible
- Rate limiting and retry logic
- Python 3.8+
- PostgreSQL 13+
- Docker (optional, for containerized deployment)
- Google Cloud Service Account (for Sheets access)
- Gradescope account with TA/Instructor access
-
Clone the repository
git clone https://github.com/yourusername/GradeSync.git cd GradeSync -
Install dependencies
pip install -r requirements_db.txt
-
Set up PostgreSQL
# macOS (using Homebrew) brew install postgresql@15 brew services start postgresql@15 createdb gradesync -
Configure environment
cp .env.example .env # Edit .env with your credentials -
Initialize database
python -c "from core.db import init_db; init_db(); print('Database initialized!')"
-
Run your first sync
cd gradescope python gradescope_to_spreadsheet.py
# 1. Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 2. Install dependencies
pip install -r requirements_db.txt
# 3. Install PostgreSQL
# macOS:
brew install postgresql@15
# Ubuntu/Debian:
sudo apt-get install postgresql-13
# 4. Create database
createdb gradesync
# 5. Initialize schema
python -c "from core.db import init_db; init_db()"# 1. Build API service
cd api
docker-compose build
# 2. Start services
docker-compose up -d
# 3. Access API
curl http://localhost:8000/Create a .env file in the project root:
# Database
DATABASE_URL=postgresql://postgres:password@localhost:5432/gradesync
USE_DB_AS_PRIMARY=true
KEEP_CSV_FILES=false # Set to 'true' to keep CSV files after importing to DB
# Gradescope credentials
GRADESCOPE_EMAIL=your-email@example.com
GRADESCOPE_PASSWORD=your-password
# Google Sheets (Service Account JSON)
SERVICE_ACCOUNT_CREDENTIALS={"type":"service_account","project_id":"your-project",...}
# PrairieLearn (optional)
PL_API_TOKEN=your-prairielearn-tokenEdit config/courses.json:
{
"gradescope_course_id": "1098053",
"spreadsheet_id": "YOUR_GOOGLE_SHEETS_ID",
"scopes": ["https://www.googleapis.com/auth/spreadsheets"],
"course_name": "The Beauty and Joy of Computing",
"department": "COMPSCI",
"course_number": "10",
"semester": "Fall",
"year": "2025",
"instructor": "",
"categories": [
{
"name": "Labs",
"patterns": ["lab", "laboratory"]
},
{
"name": "Projects",
"patterns": ["project", "proj"]
},
{
"name": "Discussions",
"patterns": ["discussion", "disc"]
},
{
"name": "Quizzes",
"patterns": ["quiz", "lecture"]
}
]
}- Create a project in Google Cloud Console
- Enable Google Sheets API
- Create a Service Account
- Download JSON key
- Share your Google Sheet with the service account email
- Add JSON contents to
SERVICE_ACCOUNT_CREDENTIALSin.env
# One-time sync
cd gradescope
python gradescope_to_spreadsheet.py
# Expected output:
# - Downloads CSVs from Gradescope
# - Saves to gradescope/data/gradescope_csvs/<course_id>/
# - Ingests into PostgreSQL
# - Updates Google Sheets Summary# Development mode
cd api
uvicorn app:app --reload --port 8000
# Production mode with Docker
docker-compose up -d api
# Test API
curl http://localhost:8000/
curl http://localhost:8000/getAssignmentJSON?class_id=YOUR_COURSE_ID# From existing CSVs
python scripts/backfill_grades.py --config config/courses.json
# Re-download from Gradescope
python scripts/backfill_grades.py --config config/courses.json --re-downloadAdd to crontab for automated syncing:
# Sync every hour
0 * * * * cd /path/to/GradeSync/gradescope && /usr/bin/python3 gradescope_to_spreadsheet.py
# Sync daily at 2 AM
0 2 * * * cd /path/to/GradeSync/gradescope && /usr/bin/python3 gradescope_to_spreadsheet.pyhttp://localhost:8000
GET /Returns API status.
GET /getGrades?class_id={course_id}&assignment_id={assignment_id}Returns grades for a specific assignment in JSON format.
Parameters:
class_id: Gradescope course IDassignment_id: Gradescope assignment ID
Response:
[
{
"Name": "Student Name",
"Email": "student@example.com",
"Total Score": "95.0",
"Max Points": "100.0",
"Status": "Graded"
}
]GET /getAssignmentJSON?class_id={course_id}Returns structured list of all assignments.
Response:
{
"labs": {
"1": {
"title": "Lab 1: Introduction",
"assignment_id": "123456"
}
},
"projects": { ... },
"discussions": { ... }
}GET /fetchAllGrades?class_id={course_id}Returns grades for all assignments and all students.
GET /getGradeScopeAssignmentID/{category}/{number}?lab_type={type}Returns assignment ID for a specific category and number.
Parameters:
category: labs, projects, discussions, lecture_quizzesnumber: Assignment numberlab_type(for labs only): 1 for conceptual, 0 for code
Python:
import requests
response = requests.get(
"http://localhost:8000/getGrades",
params={"class_id": "123456", "assignment_id": "789"}
)
grades = response.json()JavaScript:
fetch('http://localhost:8000/getAssignmentJSON?class_id=123456')
.then(response => response.json())
.then(data => console.log(data));cURL:
curl "http://localhost:8000/getGrades?class_id=123456&assignment_id=789"# 1. Build images
docker-compose build
# 2. Start all services
docker-compose up -d
# 3. Check logs
docker-compose logs -f
# 4. Stop services
docker-compose down- Use environment variables for secrets (never commit
.env) - Set up PostgreSQL backups (pg_dump)
- Configure SSL/TLS for API endpoints
- Implement rate limiting and authentication
- Use monitoring (Prometheus, Grafana)
- Set up log aggregation (ELK stack)
core/- Database operations (shared by API and sync scripts)api/- FastAPI REST servicegradescope/- Gradescope synchronization scriptsconfig/- Centralized configurationscripts/- Utility and maintenance scripts
# Database ingestion tests
pytest core/test_ingest.py -v
# API tests
pytest api/test_app.py -v
# All tests
pytest -v# Linting
flake8 core/ api/ gradescope/
# Type checking
mypy core/ api/
# Formatting
black core/ api/ gradescope/# Create migration
alembic revision --autogenerate -m "Add new column"
# Apply migration
alembic upgrade head
# Rollback
alembic downgrade -1Solution: Initialize the database schema
python -c "from core.db import init_db; init_db()"Solution: Start PostgreSQL
brew services start postgresql@15 # macOS
sudo service postgresql start # LinuxSolution: Ensure you're in the project root and dependencies are installed
pip install -r requirements_db.txt
export PYTHONPATH="${PYTHONPATH}:$(pwd)"Solution: Share your Google Sheet with the service account email
Solution: The system has built-in exponential backoff. Check logs for details.
- Check the Issues page
- Review logs:
docker-compose logs -f - Database debugging:
psql gradesync
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- UC Berkeley CS10 - Original use case and testing
- Gradescope - Assessment platform integration
- PrairieLearn - Online learning platform
- Contributors and maintainers
For questions or support, please open an issue or contact the maintainers.
Built with β€οΈ for educators and students