Skip to content

System Components ​

Detailed breakdown of each system component.

Express Server (app.js) ​

The main backend server handles all HTTP requests.

Responsibilities ​

  • Serve static files (HTML, CSS, JS)
  • Handle code submissions
  • Manage LTI authentication
  • Serve starter code templates

Key Routes ​

javascript
// Static files
app.use(express.static('.'));

// Submit code to Gradescope
app.post('/submit', async (req, res) => { ... });

// Get starter code
app.get('/starter/:filename', (req, res) => { ... });

// LTI launch
app.post('/lti/launch', (req, res) => { ... });

Configuration ​

Configured via environment variables:

  • PORT — Server port
  • SECRET — Signing key
  • COURSE_ID — Gradescope course
  • TOKEN, COOKIE — Gradescope credentials

Gradescope Module (gradescope.js) ​

Handles all Gradescope API communication.

Main Function ​

javascript
export async function submitAssg(code, course_id, stud_id, asg_id, file_name, token, cookie)

Process ​

  1. Create Blob from code string
  2. Build FormData with file and CSRF token
  3. POST to Gradescope submission endpoint
  4. Parse response for submission URL
  5. Return result

Dependencies ​

  • Native fetch API
  • FormData for multipart uploads

Code Editor (codemirror-demo.html) ​

The main student-facing interface.

Components ​

CodeMirror Editor ​

javascript
const editor = CodeMirror.fromTextArea(textarea, {
  mode: "python",
  theme: "material-darker",
  lineNumbers: true,
  indentUnit: 4
});

Pyodide Runtime ​

javascript
const pyodide = await loadPyodide({
  indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/"
});

Tab Navigation ​

Switches between Code and Output views in iframe mode.

Input Handler ​

Manages inline input() calls:

javascript
async function requestInlineInput(promptText) {
  return new Promise((resolve) => {
    inputArea.style.display = 'flex';
    inputField.focus();
    inputResolve = resolve;
  });
}

Event Handlers ​

ButtonAction
Run CodeExecute with Pyodide
Submit CodePOST to /submit
ClearReset editor
HelpShow help modal

Starter Code System ​

Provides pre-filled code templates for assignments.

Server Endpoint ​

javascript
app.get('/starter/:filename', (req, res) => {
  const filepath = path.join('starters', req.params.filename);
  const code = fs.readFileSync(filepath, 'utf-8');
  res.json({ code });
});

Client Loading ​

javascript
async function loadStarterCode(filename) {
  const res = await fetch('/starter/' + filename);
  const data = await res.json();
  editor.setValue(data.code);
}

File Location ​

Starter files are stored in starters/ directory:

starters/
├── lab1_starter.py
├── lab2_starter.py
└── example.py

Help System ​

Built-in help modal for students.

Components ​

  • Help button (? icon)
  • Modal overlay
  • Sectioned content

Content Sections ​

  1. Navigation — How to use tabs
  2. Actions — What each button does
  3. Tips — Common issues and solutions
  4. Credits — Team information

Drag-to-Resize ​

Allows students to resize the editor in iframe mode.

Implementation ​

javascript
handle.addEventListener('mousedown', (e) => {
  dragging = true;
  startY = e.clientY;
  startH = shell.offsetHeight;
});

document.addEventListener('mousemove', (e) => {
  if (dragging) {
    const newH = Math.min(maxH, Math.max(minH, startH + e.clientY - startY));
    shell.style.height = newH + 'px';
  }
});

Constraints ​

  • Minimum height: 200px
  • Maximum height: 92% of viewport
  • Default height: 420px

External Dependencies ​

CDN Resources ​

ResourceVersionPurpose
CodeMirror5.65.16Code editor
Pyodide0.24.1Python runtime
Bootstrap5.3.3UI framework

npm Packages ​

PackagePurpose
expressWeb server
dotenvEnvironment variables
handlebarsTemplates
node-html-parserHTML parsing

Released under the MIT License.