pypad-notebook
Read, write and convert PyPad notebooks (.pypad.py) and Jupyter notebooks (.ipynb). Standard library
only; Python 3.9+.
PyPad is a small in-browser Python notebook for teaching: it runs entirely in the learner's browser, fits in a Moodle quiz question, can be shared as a link, and its files are plain, readable Python. This package is the file-format side of it, so a notebook is never trapped.
pip install pypad-notebook
Command line
pypad convert lesson.pypad.py # -> lesson.ipynb
pypad convert lesson.ipynb # -> lesson.pypad.py
pypad convert lesson.ipynb --outputs text
pypad check lesson.pypad.py # ok / changed / absent: is it still what PyPad wrote? (exit 1 if changed)
pypad embed lesson.pypad.py > question.html # the HTML block for a Moodle question or web page
pypad answers responses.csv --out answers/ # split a Moodle quiz "Responses" download into one file per student
pypad verify template.pypad.py answers/*.pypad.py # re-check them against the template (exit 1 if any are not clean)
pypad embed lesson.pypad.py --answer-format base64 --loader https://pypad.dev/v1/pypad-mdl-quiz.js
convert never overwrites without --force. check, convert and embed also accept an HTML page that holds a notebook (an embed, or a
PyPad "web page" export).
Marking
An assessment that matters should be checked where the student cannot touch it. The widget stops mistakes in the student's browser, but the browser is
the student's. pypad verify applies, on your side, the same rules the widget applies when it opens an answer (the template's policy, its locked cells,
its answer cells and sections), and tells you for each answer what the student changed, added or removed, and what the rules would have put back:
answers/Student_Sam.pypad.py: clean (check value ok) - changed a1
answers/Other_Oz.pypad.py: NOT CLEAN (check value ok) - changed a1
cell "i1" cannot be edited, and its text was put back
pypad answers turns a Moodle quiz Responses download (CSV) into those files, decoding stored answers.
In Python
import pypad
result = pypad.parse(open("lesson.pypad.py", encoding="utf-8").read())
result.integrity # 'ok', 'changed' or 'absent'
result.warnings # problems found while reading; a damaged file still opens
nb = result.notebook # nb.config, nb.cells[i].id / .type / .source / .settings / .outputs
text = pypad.dumps(nb) # .pypad.py text, with its check value
ipynb = pypad.to_ipynb_text(nb, save_outputs="text")
nb2 = pypad.from_ipynb_text(open("lesson.ipynb", encoding="utf-8").read())
html = pypad.build_embed(text, answer_format="plain")
report = pypad.verify_answer(template_nb, answer_nb, integrity) # report.clean, .changed_cells, .violations, ...
It matches the JavaScript implementation
This is a port of the reference implementation (packages/notebook in the PyPad repository). The same text produces the same notebook, the
same file, the same Jupyter notebook and the same check value, including for emoji and odd characters. That is tested against a file of vectors
that the JavaScript implementation generates (tests/vectors.json), so the two cannot drift apart unnoticed.
The format, in one screen
# %% [pypad-start] v1 sha=3f9a1c0d7b2e4a65
# %% [config] {"policy":"fixed","kernel":"skulpt"}
# %% [markdown] {"id":"k3j9a0xq","editable":false}
"""
Print the sum of 1 and 2.
"""
# %% [code] {"id":"p8w2m1zc"}
print(1 + 2)
# %% [pypad-end]
Code is code and everything else sits in triple-quoted strings, so the file is (nearly) valid Python and readable anywhere. The sha is a check
value of the notebook's content: it notices an editor or a hand edit changing something, and ignores indentation and line endings. It is not a
security measure. Reading is forgiving (Jupytext-style comment blocks, indented text, Windows line endings); writing has one form.
MIT licensed.
Metadata
Release files for pypad-notebook 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pypad_notebook-0.1.0.tar.gz | 50.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pypad_notebook-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 84.4 kB
Release files / pypad_notebook-0.1.0.tar.gz
| Download URL | pypad_notebook-0.1.0.tar.gz |
|---|---|
| Size | 50.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6d4697b15f54313a076feff8063ff28a8b2b7de09eed5c39cda53ee1fe4100b2
|
|
BLAKE2b-256 checksum How to use checksums |
6c1a258f78b80b4da003f74aca6c231d8188e263940d362edd1c978949ef1bef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / pypad_notebook-0.1.0-py3-none-any.whl
| Download URL | pypad_notebook-0.1.0-py3-none-any.whl |
|---|---|
| Size | 33.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8813a3e76e9901a411de831985fd15293b5970b4da1ddc342fcd4a8ede853be0
|
|
BLAKE2b-256 checksum How to use checksums |
52423ae75289c578787221607666720937da7018afdb32df4ef3c515b21da46a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log