Architecture Overview
High-level system architecture of the Gradescope Submitter.
System Diagram
┌─────────────────────────────────────────────────────────────────┐
│ D2L Brightspace │
│ ┌─────────────┐ │
│ │ Quiz Page │ ──── iframe ────┐ │
│ └─────────────┘ │ │
└──────────────────────────────────┼──────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Gradescope Submitter │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ login.html │ -> │ codemirror- │ -> │ /submit │ │
│ │ (Sign In) │ │ demo.html │ │ endpoint │ │
│ └─────────────┘ │ (Editor) │ └────────┬────────┘ │
│ └──────────────┘ │ │
│ │ │ │
│ ┌─────┴─────┐ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Run Code │ │ Submit │ │ gradescope.js│ │
│ │ (Pyodide)│ │ Code │ │ (API calls) │ │
│ └──────────┘ └──────────┘ └──────────────┘ │
│ │ │
└─────────────────────────────────────────────────┼──────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Gradescope │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Authentication │ │ Code Submission │ │
│ │ (TOKEN/COOKIE) │ │ & Auto-grading │ │
│ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘Technology Stack
Frontend
| Technology | Purpose |
|---|---|
| HTML/CSS/JS | Core web technologies |
| CodeMirror | Code editor with syntax highlighting |
| Pyodide | Python interpreter in WebAssembly |
| Bootstrap | UI components and styling |
Backend
| Technology | Purpose |
|---|---|
| Node.js | JavaScript runtime |
| Express | Web server framework |
| dotenv | Environment variable management |
| Handlebars | Template engine |
External Services
| Service | Purpose |
|---|---|
| D2L Brightspace | Learning Management System |
| Gradescope | Automated code grading |
Key Design Decisions
1. Browser-Based Python Execution
Decision: Use Pyodide for in-browser Python execution.
Rationale:
- No server round-trips for running code
- Instant feedback for students
- Reduces server load
- Works offline after initial load
Trade-offs:
- Initial load time for Pyodide (~5MB)
- Some Python features unavailable (networking, system calls)
2. Iframe Embedding
Decision: Embed the editor in D2L quizzes via iframe.
Rationale:
- Seamless integration with existing D2L workflow
- Students don't leave the quiz environment
- Quiz context preserved
Trade-offs:
- Requires HTTPS
- Limited by iframe security policies
- Resizing can be tricky
3. Server-Side Gradescope Submission
Decision: Submit to Gradescope through our server, not directly from browser.
Rationale:
- Credentials stay server-side (security)
- CORS restrictions prevent direct browser calls
- Centralized logging and error handling
Trade-offs:
- Server is a single point of failure
- Credentials must be managed on server
4. Stateless Sessions
Decision: Store minimal state, use URL parameters for context.
Rationale:
- Simpler architecture
- No database required
- Easy horizontal scaling
Trade-offs:
- URL parameters visible to users
- No persistent user preferences
File Structure
gradescope-submitter/
├── app.js # Main Express server
├── gradescope.js # Gradescope API submission logic
├── .env # Environment variables
├── package.json # Dependencies
│
├── Frontend
│ ├── codemirror-demo.html # Main code editor
│ ├── login.html # Gradescope sign-in
│ └── mockD2L.html # Demo D2L interface
│
├── styles/
│ └── global.css # Shared styles
│
├── starters/ # Starter code templates
│ └── *.py
│
├── testing/ # Jest tests
│ └── *.test.js
│
└── docs/ # This documentationNext Steps
- System Components — Detailed component breakdown
- Data Flow — How data moves through the system
- Security — Security considerations