Skip to main content

QuestionBankToolkit

QuestionBankToolkit validates question banks written in YAML, builds QTI 1.2 ZIP packages for Canvas, and extracts supported QTI 1.2 questions into YAML. The current scope is single-answer multiple-choice questions. QTI imports and structural checks reject XML document type declarations (DTDs), entity declarations, and external entity references. Python 3.14 or newer is required.

Install the released package from PyPI:

python -m pip install QuestionBankToolkit

See the YAML schema and the sample bank for the source format. The documentation site provides the complete user guide, schema, command reference, and Python API reference. The optional bank field default_shuffle_choices controls answer-choice shuffling in generated QTI, and a question-level shuffle_choices boolean can override it. If both fields are omitted, shuffling defaults to false.

Start here

The beginner workflow explains Python installation on Windows, macOS, and Linux; provides a complete copyable bank; and walks through validation, build review, and Canvas upload. The generated COURSE_BANK_ID_QTI12.zip file is the file uploaded to Canvas.

After installation, validate a YAML bank with:

coursebanks validate examples/sample_course/questions.yaml

The command reports invalid fields and rejects malformed YAML, duplicate mapping keys, and nonfinite grading points or time estimates. See the validation rules for supported values and diagnostics. See the command reference and troubleshooting guide for every command's output, exit status, file policy, and common errors.

Optional: importing QTI

Import a supported QTI 1.2 ZIP package into a new YAML bank with:

coursebanks import-qti questions.zip --course COURSE123 --bank-id ImportedBank --title "Imported bank" --out imported.yaml

The importer supports a strict single-answer multiple-choice subset, including Canvas Common Cartridge item-bank exports, and rejects unsupported or ambiguous structures. See the QTI import guide for required package structure, defaults, choice-label normalization, metadata CSV overrides, and the field-by-field compatibility table.

Optional: selecting and recording questions

Assessment names can describe exams, weekly quizzes, or homework. A question's optional assessments list restricts where it can be used; an empty or omitted list allows any assessment.

coursebanks select questions.yaml --assessment "Homework 1" --count 5
coursebanks record questions.yaml --term 2027-Fall --assessment "Homework 1" --ids Q01 Q02
coursebanks plan questions.yaml --terms 2027-Fall 2028-Spring --assessment "Quiz 1" 3 --assessment "Homework 1" 2 --out plan.csv

Selection and planning only propose questions; record the IDs actually administered. Counts are nonnegative integers and plan counts apply in each term. Repeat --assessment NAME COUNT for each planned assessment; this replaces the former --midterm and --final plan options. Selection and recording still accept --exam as an alias for --assessment. All three commands accept --history PATH (default usage.csv), and selection and planning accept --seed for reproducible proposals. Recorded questions cannot be reused within the same course and bank, even for a different assessment. New history and plan CSVs use the column assessment; legacy histories with an exam column remain readable and keep that header when appended.

Existing YAML banks are converted on load without changing their files or schema version. See migration details for the legacy-value mapping and QTI metadata behavior.

For contributors

Check that python --version reports Python 3.14 or newer. From the repository root, use that interpreter to create and activate a virtual environment, then install the package and development tools:

python -m venv .venv

On Linux or macOS, activate it with source .venv/bin/activate. On Windows PowerShell, use .venv\Scripts\Activate.ps1.

python -m pip install -e . --group dev
python -m pytest

Tests use synthetic questions and do not require private course content or Canvas access.

With the environment activated, run all development checks using:

./scripts/run_checks.sh

The script runs pytest, Ruff lint and formatting, strict mypy, strict BasedPyright, and pydoclint. See the developer guide for individual commands, environment configuration, and the typed Python API. For Python callers, load_bank returns a validated bank; use load_yaml to edit incomplete drafts and parse_bank to validate and construct a bank from draft data.

Metadata

Release files for QuestionBankToolkit 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for QuestionBankToolkit 0.2.0
File Size Uploaded Provenance
questionbanktoolkit-0.2.0.tar.gz 135.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for QuestionBankToolkit 0.2.0
File Interpreter ABI Platform
questionbanktoolkit-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 193.0 kB

Release files / questionbanktoolkit-0.2.0.tar.gz

Download URL questionbanktoolkit-0.2.0.tar.gz
Size 135.8 kB
Tags Source
SHA-256 checksum
How to use checksums
395dd672c5962ac3ef8cd3b8da3277f6c157ca59b56e087234eb159d2c4fa2ba
BLAKE2b-256 checksum
How to use checksums
c27f447c248dc8487b288db470080b494fd7c06a32e83ad70dd99601dea701d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.8

Release files / questionbanktoolkit-0.2.0-py3-none-any.whl

Download URL questionbanktoolkit-0.2.0-py3-none-any.whl
Size 57.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b2962d6417a4b90d17c0890c3f62ee96d9923ee5c890058d4f38b765811c8149
BLAKE2b-256 checksum
How to use checksums
cf016aed54974900c1d10dd29fd9f801a4bf5f316d27f10927e7c17dff8602e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.8

Security for QuestionBankToolkit 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page