Utilities for building question banks and generating exam documents.
Project description
PromptuKit
Utilities for building and managing multiple-choice question banks and generating exam PDFs.
Install from PyPI
pip install promptukit
The package is published at https://pypi.org/project/promptukit/. After installing you get the CLI entry points on your PATH:
add-question
extract-question --help
validate-question
question-bank --help
You can also import the library in Python or a Jupyter notebook:
import promptukit as pk
# Top-level helpers: pk.load(path), pk.save(path, data), pk.pick(), pk.confirm()
# Subpackages are available as `pk.exams`, `pk.questions`, and `pk.utils`.
Quick Notebook Walkthrough
Here are short, copy-pasteable examples you can run inside a Jupyter notebook to load a question bank, validate it, and generate a PDF exam.
# 1) Import helpers
import promptukit as pk
from promptukit.questions import validate_question
from promptukit.exams import create_exam
# 2) Load a question bank (path relative to the repository root). If you're
# running outside the repository (for example from an installed package),
# fall back to the packaged sample dataset that ships with `promptukit`.
import os
bank_path = 'content/question_banks/example_sections.json'
if os.path.exists(bank_path):
data = pk.load(bank_path)
else:
# load packaged sample included with the installed package
data = pk.load_resource('question_banks/example_sections.json')
# 3) Inspect the file (section-based vs flat list)
if 'sections' in data:
print('Sections:', [s.get('title') for s in data['sections']])
print('First question:', data['sections'][0]['questions'][0])
elif 'questions' in data:
print('Total questions:', len(data['questions']))
print('First question:', data['questions'][0])
else:
print('Unexpected file shape:', type(data))
# 4) Validate programmatically
errors, warnings = validate_question.validate(data)
if errors:
print('Validation errors:', errors)
else:
print('Bank valid — warnings:', warnings)
# 5) Generate a PDF exam from the same bank (we already have `data` loaded
# above as a dict, so pass it directly). Note: PDF generation requires
# the `reportlab` package: `pip install reportlab`.
create_exam.build_exam_pdf(data, 'notebooks/output_exam.pdf')
Notes
- If you only want to run the library functions without Poetry activation, you
can run modules with
python -m promptukit.questions.extract_questionorpython -m promptukit.exams.create_examas shown elsewhere in this README. - Generating PDFs requires
reportlab(install withpip install reportlab).
Try the interactive Colab demo
If you'd like a runnable notebook that demonstrates the Quick Notebook Walkthrough, open the Colab demo:
https://colab.research.google.com/drive/1vzaUML_8nkWKhOfauv5MXPE-dQ5sXFF_?usp=sharing
Quick tips for Colab:
- To use the published package on PyPI:
!pip install promptukit reportlab
- To run the repository version (latest changes), clone and install from GitHub:
!git clone https://github.com/jrkasprzyk/promptukit.git
%cd promptukit
!pip install -e .
- The Colab notebook includes cells that use
pk.load_resource(...)as a fallback when localcontent/files aren't available.
Getting started (Poetry, for development)
-
Install Poetry (if you don't have it):
pip install --user poetry
-
Create the virtual environment and install dependencies:
poetry install -
Run the CLI tools via Poetry (console scripts / entry points):
poetry run add-question poetry run extract-question --help poetry run validate-question poetry run question-bank --help
Activating the virtualenv
If Poetry is configured to create an in-project virtualenv, it will be
placed in a .venv folder at the repository root. Activate that
environment from the project root using the command for your shell.
PowerShell (Windows):
.\.venv\Scripts\Activate.ps1
If script execution is blocked, temporarily allow it then activate:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
.\.venv\Scripts\Activate.ps1
Command Prompt (cmd.exe):
.\.venv\Scripts\activate.bat
Git Bash / MSYS (Windows):
source .venv/Scripts/activate
macOS / Linux (POSIX):
source .venv/bin/activate
Alternatives (no manual activation required):
# Run a single command inside the virtualenv without activating it
poetry run <cmd> # e.g. poetry run pytest
Poetry 2.x note:
- The
poetry shellcommand (which previously spawned a new shell) is not installed by default in Poetry 2.0+. You can either usepoetry env activate(then evaluate the printed activation command in your shell) or install the shell plugin to restorepoetry shell.
Notes
- The package entry points are defined in
pyproject.tomlunder[tool.poetry.scripts]and map console script names to themain()functions in the modules under thepromptukitpackage.
Usage Examples
Quick (Poetry):
poetry run add-question
poetry run extract-question --list-categories
poetry run validate-question
poetry run question-bank extract --help
Extracting data:
# List categories and available fields
poetry run extract-question --list-categories
# Print prompt and answer fields for the 'music' category
poetry run extract-question --file content/question_banks/block-doku-questions.json --category music --fields prompt,answer
# Interactive picker
poetry run extract-question -i
Add questions:
# Interactive add
poetry run add-question
# Batch mode
poetry run add-question --batch new_questions.json content/question_banks/mybank.json
Validate a trivia file:
# Validate the default question bank
poetry run validate-question
# Validate a specific file
poetry run validate-question content/question_banks/block-doku-questions.json
Manage files with question-bank (create/copy/extract):
# Create a new template JSON file
poetry run question-bank create --dest content/question_banks/new.json --categories music,film-and-tv
# Copy an existing file
poetry run question-bank copy --src content/question_banks/block-doku-questions.json --dest content/question_banks/backup.json
# Extract a subset (easy music questions)
poetry run question-bank extract --src content/question_banks/block-doku-questions.json --dest content/question_banks/music_easy.json --categories music --difficulty easy
# Interactive extract
poetry run question-bank extract -i --src content/question_banks/block-doku-questions.json --dest content/question_banks/pick.json
Alternative: run modules with python -m when not using Poetry:
python -m promptukit.questions.add_question
python -m promptukit.questions.extract_question --help
python -m promptukit.questions.question_bank create --dest content/question_banks/new.json
Create exam PDF
The create_exam.py script can generate a printable exam PDF. It accepts
an external JSON question bank so you can build exams from your existing
content/question_banks/ files.
Usage (from the repository root):
# Use the built-in hard-coded exam
python -m promptukit.exams.create_exam
# Load questions from a JSON bank and write a PDF
python -m promptukit.exams.create_exam -q content/question_banks/block-doku-questions.json -o cven4333_from_json.pdf
# With Poetry (runs the module inside the virtualenv)
poetry run python -m promptukit.exams.create_exam -q content/question_banks/block-doku-questions.json -o cven4333_from_json.pdf
Supported JSON formats
-
Top-level
sections(preferred):{ "sections": [ { "title": "Section title", "questions": [ { "prompt": "...", "choices": ["...", "..."] }, ... ] } ] }
-
categoriesis an alias forsectionsand is also accepted. -
Flat list of questions (top-level array) or top-level object with
questionsarray:{ "questions": [ { "prompt": "...", "choices": ["...", "..."], "category": "Section title" }, ... ] }
-
Question objects support multiple common field names:
prompt,q,question, ortextfor the question text;choicesoranswersfor the answer options; optionalcategoryto group flat lists into sections. -
If choices are not already labeled (for example "Oceans" instead of "A) Oceans"), the script will prefix them with
A),B), etc. Prompts without a leading number will be auto-numbered sequentially.
Example files
- Example section-based bank: content/question_banks/example_sections.json
- JSON Schema describing accepted layouts: content/question_banks/question_schema.json
Behavior notes
- If no
-q/--questionsfile is provided to the exam generator, the script falls back to the built-in hard-coded 60-question exam and preserves its original 8-section breakdown. - When you provide a section-based JSON file the PDF's section headings will
be taken from each section's
title(orname/labelif present). When you provide a flat list withcategoryfields, the loader will group questions by category to build sections automatically.
Running Tests
The test suite lives under dev/checks. The file
dev/checks/test_question_tool.py contains unit tests that exercise the
question-bank helpers and CLI-style interfaces.
Run the tests:
Using Poetry (recommended):
poetry install
poetry run pytest -q
Or run a single file directly:
poetry run pytest dev/checks/test_question_tool.py -q
Notes:
- Tests use pytest's
tmp_pathfixture and do not modify your repository files.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file promptukit-0.1.281.tar.gz.
File metadata
- Download URL: promptukit-0.1.281.tar.gz
- Upload date:
- Size: 31.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6fefc0804bfa5949aad447da11318151f34e8028d3684fd5035c36a4bed9728f
|
|
| MD5 |
40e015b3654f413f81015f822d6a9039
|
|
| BLAKE2b-256 |
a2a719eabdb3967b7654de8030e3a7439d1bc661e4e982df03ae6650b48d2ec8
|
Provenance
The following attestation bundles were made for promptukit-0.1.281.tar.gz:
Publisher:
python-publish.yml on jrkasprzyk/promptukit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promptukit-0.1.281.tar.gz -
Subject digest:
6fefc0804bfa5949aad447da11318151f34e8028d3684fd5035c36a4bed9728f - Sigstore transparency entry: 1338935453
- Sigstore integration time:
-
Permalink:
jrkasprzyk/promptukit@86d0eaf628b6c724c1c827335a98e607e2035ff0 -
Branch / Tag:
refs/tags/v0.1.281 - Owner: https://github.com/jrkasprzyk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@86d0eaf628b6c724c1c827335a98e607e2035ff0 -
Trigger Event:
release
-
Statement type:
File details
Details for the file promptukit-0.1.281-py3-none-any.whl.
File metadata
- Download URL: promptukit-0.1.281-py3-none-any.whl
- Upload date:
- Size: 34.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc51ce0afd28a1b401ddb46ea239a044b0e963da26e68f4b86be46a133e93a7d
|
|
| MD5 |
85b57aa10d73594f0663c328fdcfaedb
|
|
| BLAKE2b-256 |
eef63c2c93be7e077cf47a08f37f6465ed949174a6465ee8afe30e39efbc0726
|
Provenance
The following attestation bundles were made for promptukit-0.1.281-py3-none-any.whl:
Publisher:
python-publish.yml on jrkasprzyk/promptukit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promptukit-0.1.281-py3-none-any.whl -
Subject digest:
bc51ce0afd28a1b401ddb46ea239a044b0e963da26e68f4b86be46a133e93a7d - Sigstore transparency entry: 1338935458
- Sigstore integration time:
-
Permalink:
jrkasprzyk/promptukit@86d0eaf628b6c724c1c827335a98e607e2035ff0 -
Branch / Tag:
refs/tags/v0.1.281 - Owner: https://github.com/jrkasprzyk
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@86d0eaf628b6c724c1c827335a98e607e2035ff0 -
Trigger Event:
release
-
Statement type: