Flask application skeleton with SQLAlchemy models for courses (including per-course settings), students, enrollments, opt-outs, and calls; the weighted and cycle selection logic ported from the manual coldcall scripts; alembic migrations; and a pytest suite covering selection behavior and the model query helpers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
66 lines
2.6 KiB
Markdown
66 lines
2.6 KiB
Markdown
# coldcall-lti
|
|
|
|
A Canvas external tool (LTI 1.3) for managing cold calls in case-based
|
|
classes: it selects students to call using weighted randomness, records
|
|
what happened with each call, lets students report planned absences, and
|
|
reports participation data back to both instructor and students. It
|
|
replaces a manual workflow built on exported rosters, Google Forms, and
|
|
local scripts.
|
|
|
|
## How it works
|
|
|
|
The tool is a Flask application that Canvas launches over LTI 1.3. A
|
|
single URL serves everyone: Canvas identifies the person and course on
|
|
each launch, so instructors get the call-list and reporting views while
|
|
students get the absence form and their own history. The roster comes
|
|
from Canvas through the Names and Role Provisioning Service, which means
|
|
adds and drops are picked up automatically rather than reconciled by
|
|
hand.
|
|
|
|
Selection uses the same weighting as the manual system it replaces: each
|
|
answered call divides a student's weight by the course's weight factor
|
|
(default 2), so students who have answered more questions become
|
|
progressively less likely to be called. Each course can instead use
|
|
"cycle" mode, which shuffles the roster and calls everyone exactly once.
|
|
These, along with whether students can see their own assessments, are
|
|
per-course settings.
|
|
|
|
## Layout
|
|
|
|
- `coldcall_lti/models.py` — SQLAlchemy models: courses (with their
|
|
settings), students, enrollments, opt-outs, and calls, plus the query
|
|
helpers that feed selection.
|
|
- `coldcall_lti/selection.py` — the weighted and cycle selection logic.
|
|
Kept free of database and web dependencies so it can be tested and
|
|
reasoned about on its own.
|
|
- `coldcall_lti/__init__.py` — the Flask application factory.
|
|
- `migrations/` — alembic migrations. The schema avoids
|
|
database-specific types so the same migrations run on SQLite (the
|
|
default) and MariaDB/MySQL; switching is a matter of changing
|
|
`COLDCALL_DATABASE_URL`.
|
|
- `tests/` — pytest suite covering selection behavior and the model
|
|
helpers.
|
|
|
|
## Setup
|
|
|
|
Development uses a virtualenv that shares the system's Debian-packaged
|
|
libraries (Flask, SQLAlchemy, alembic, pytest) and adds the one
|
|
PyPI-only dependency, the maintained `pylti1p3next` fork of PyLTI1p3:
|
|
|
|
```
|
|
python3 -m venv --system-site-packages .venv
|
|
.venv/bin/pip install pylti1p3next
|
|
.venv/bin/pip install -e .
|
|
```
|
|
|
|
Create the database and run the tests:
|
|
|
|
```
|
|
.venv/bin/python -m alembic upgrade head
|
|
.venv/bin/python -m pytest tests/
|
|
```
|
|
|
|
Configuration is by environment variable: `COLDCALL_DATABASE_URL` (any
|
|
SQLAlchemy URL; defaults to an SQLite file under `instance/`) and
|
|
`COLDCALL_SECRET_KEY` for Flask sessions.
|