Question-bank YAML schema (v1)¶
The file contains one UTF-8 YAML document whose top level is a mapping.
Bank and question field names must be strings.
All top-level fields below are required except default_shuffle_choices.
Readers new to YAML should begin with the complete authoring and build walkthrough.
Field |
Meaning |
|---|---|
|
Integer |
|
Nonempty course identifier text, for example |
|
Stable identifier matching |
|
Nonempty Canvas assessment display title |
|
Optional boolean controlling QTI choice shuffling for questions without an override; default |
|
Nonempty ordered list of question mappings |
Each question is a mapping with the fields below.
All fields are required except format (default plain), assessments (default unrestricted), and shuffle_choices (default inherited from the bank).
Field |
Valid values |
|---|---|
|
Unique stable identifier matching |
|
Nonempty short instructor title |
|
Nonempty broad coverage area for rotation |
|
Nonempty specific topic |
|
|
|
Optional list of unique, nonempty assessment names; omitted or |
|
Finite positive number of estimated minutes; booleans and quoted numbers are rejected |
|
Finite positive number of grading points; booleans and quoted numbers are rejected |
|
|
|
Optional boolean overriding |
|
Nonempty complete question text (Unicode text or authored HTML) |
|
Ordered mapping of at least two choice keys to nonempty, distinct text options; |
|
String matching exactly one choice key |
|
Nonempty instructor explanation and Canvas feedback |
Validation rules¶
Identifiers and choice keys must start with an ASCII letter, followed only by ASCII letters, digits, underscores, hyphens, or periods.
Choice keys must be strings; quote labels such as yes or no that YAML may otherwise interpret as booleans.
Difficulty values such as Basic are case-sensitive.
Assessment names are user-defined and matched exactly, including case and whitespace; quote numeric names such as "1".
Use assessments: ["Homework 1", "Quiz 2"] to restrict eligibility.
Text fields cannot be empty or contain only whitespace.
Question IDs must be unique within the bank. Question stems must also be unique after converting to lowercase and collapsing whitespace. Choice text must be unique within each question after removing leading and trailing whitespace; this comparison is case-sensitive. These comparisons detect duplicates without changing the stored text.
Points and minutes accept integers and decimal numbers greater than zero.
Zero, negative values, booleans, NaN (.nan), and infinity (.inf or -.inf) are invalid.
Shuffle settings must be YAML booleans written as true or false, without quotation marks.
During QTI export, shuffle_choices takes precedence over default_shuffle_choices; if both are omitted, choices are not shuffled.
The exporter writes the effective setting as shuffle="Yes" or shuffle="No" on render_choice.
Duplicate YAML mapping keys are rejected at every level, including optional metadata, instead of silently keeping the last value.
YAML merge keys (<<) are unsupported; write fields explicitly so overrides cannot hide duplicate definitions.
Loading accepts only safe YAML data and rejects custom object constructors and multiple documents in one file.
Recursive aliases are rejected; nonrecursive aliases retain their values as independent copies.
Optional metadata may contain dates, binary values, sets, and nested mappings with scalar keys.
Additional optional YAML metadata can be kept for authoring (for example outcome, tags, or last_reviewed).
Loading and saving preserve these values, but schema validation ignores their meaning and QTI export does not include them.
The recognized optional fields assessments, format, default_shuffle_choices, and shuffle_choices control documented toolkit behavior.
Validation does not insert defaults or modify the bank and does not verify HTML rendering or Canvas compatibility.
After installing the tool, check a bank with:
coursebanks validate examples/sample_course/questions.yaml
A valid bank produces a Valid: summary and exit code 0.
Invalid content produces an ERROR: diagnostic and exit code 2.
Question diagnostics identify the question position, supplied ID, and invalid field; YAML syntax and duplicate-key errors include file and line information.
Sample item¶
- id: M1C01
title: Continuum length scale
area: Continuum / fluids and stress
topic: Continuum assumptions
difficulty: Basic
assessments: []
minutes: 1.5
points: 2
format: plain
stem: If the characteristic length increases tenfold at fixed mean free path, how does Kn change?
choices:
A: It decreases tenfold.
B: It increases tenfold.
C: It does not change.
D: It becomes the Reynolds number.
answer: A
explanation: Kn is the ratio of mean free path to characteristic length.
For a complete bank containing the top-level fields, start from the sample bank.
Avoid custom LaTeX macros in question stems. For Canvas, start with clear Unicode mathematics. Test any HTML math formatting in Canvas before release. No general LaTeX-to-Canvas equation converter is included.
Migrating existing banks¶
Schema version remains 1 during active development.
Loading a validated bank converts legacy exam: Midterm to assessments: [Midterm], exam: Final to assessments: [Final], and exam: Either to assessments: [].
Other nonempty legacy names become single-element lists.
Do not supply both fields on the same question.
The special meaning of Either applies only to the legacy field; assessments: [Either] refers to an assessment literally named Either.
Validation and loading leave the source file unchanged.
QTI export stores eligibility as a JSON array in the assessments metadata field; import restores it.
QTI import reads the optional render_choice shuffle attribute, treats an omitted attribute as No, and stores the effective result in each question’s shuffle_choices field.
Import also accepts legacy suggested_exam metadata, using unrestricted eligibility if neither metadata field exists.
An optional import metadata CSV keyed by ID can override eligibility using an Assessments column containing a JSON array or the legacy Suggested exam column.
Precedence is CSV Assessments, CSV Suggested exam, QTI assessments, then QTI suggested_exam; empty CSV cells supply no override.
Use [] to explicitly override restrictions with unrestricted eligibility.
The generated question catalog also represents assessments as a JSON array.
See the QTI import guide for the complete preservation, normalization, defaulting, and CSV precedence contract.