Generate exercise versions of Jupyter notebooks
Project description
ipynb-scrubber
Generate exercise versions of Jupyter notebooks by clearing solution cells and removing instructor-only content.
[!NOTE] This is a project made to satisfy a need on some personal projects. The behaivor has been tested to work for these projects but will not be supported for other uses.
Issues will be reviewed if opened, and any legitimate bugs will be fixed, but new features or ideas will likely be rejected unless accompanied by a working pull request with comprehensive tests.
Thanks for understanding.
Features
- Clear solution cells: Replace cell contents with placeholder text while preserving structure
- Remove cells entirely: Omit instructor-only cells from the output
- Preserve structure: Maintain notebook structure and metadata
- Clear all outputs: Remove all cell outputs and execution counts for a clean slate
- Support for tags: Use cell tags or Quarto-style options to mark cells
- Simple CLI: Unix-style tool that reads from stdin and writes to stdout
Installation
Install with a python package manager like pip or uv:
pip install ipynb-scrubber
Usage
The tool takes a notebook on stdin and will write the scrubbed version to
stdout:
ipynb-scrubber < input.ipynb > output.ipynb
Options
--clear-tag TAG: Tag marking cells to clear (default:scrub-clear)--clear-text TEXT: Replacement text for cleared cells (default:# TODO: Implement this)--omit-tag TAG: Tag marking cells to omit entirely (default:scrub-omit)
Examples
Using default settings:
ipynb-scrubber < lecture.ipynb > exercise.ipynb
Using custom tags:
ipynb-scrubber --clear-tag solution --omit-tag private < lecture.ipynb > exercise.ipynb
Using custom placeholder text:
ipynb-scrubber --clear-text "# YOUR CODE HERE" < lecture.ipynb > exercise.ipynb
Marking Cells
There are two ways to mark cells for processing:
1. Cell Tags
Add tags to cells using Jupyter's tag interface:
- Add
scrub-cleartag to solution cells that should be cleared - Add
scrub-omittag to cells that should be removed entirely
2. Quarto Options
Use Quarto-style cell options at the beginning of code cells:
#| scrub-clear
def secret_solution():
return 42
#| scrub-omit
# This cell will be removed entirely
print("Instructor only!")
Example
Input "notebook"
# Cell 1 - Instructions (no tags)
# This will remain unchanged
print("Exercise: implement the function below")
# Cell 2 - Solution (tagged: scrub-clear)
def add(a, b):
return a + b
result = add(1, 2)
print(f"Result: {result}")
# Cell 3 - Test (tagged: scrub-omit)
# This cell will be removed
assert add(1, 2) == 3
print("Tests pass!")
Output "notebook"
# Cell 1 - Instructions (unchanged)
# This will remain unchanged
print("Exercise: implement the function below")
# Cell 2 - Solution (cleared)
# TODO: Implement this
# (Cell 3 is omitted entirely)
Behavior
- All cell outputs are cleared: Every cell has its output and execution count removed
- Tagged cells are processed:
- Cells with the clear tag have their source code replaced with placeholder text
- Cells with the omit tag are removed entirely from the output
- Notebook metadata: An
exercise_versionflag is added to the notebook metadata - Error handling: Invalid notebooks produce helpful error messages
License
Apache License 2.0
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
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 ipynb_scrubber-0.1.0.tar.gz.
File metadata
- Download URL: ipynb_scrubber-0.1.0.tar.gz
- Upload date:
- Size: 32.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c79016f9ca100d61481ad47b3f03bde3a1820e4e4f3e137409e723032319fbf1
|
|
| MD5 |
7f539fc9512ce62be3a311c772d3815d
|
|
| BLAKE2b-256 |
349ecb19a0ec717bf37a7e02023cf343f11b88ea297fbf2a340f89831a39ae80
|
Provenance
The following attestation bundles were made for ipynb_scrubber-0.1.0.tar.gz:
Publisher:
release.yml on jkeifer/ipynb-scrubber
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ipynb_scrubber-0.1.0.tar.gz -
Subject digest:
c79016f9ca100d61481ad47b3f03bde3a1820e4e4f3e137409e723032319fbf1 - Sigstore transparency entry: 428815773
- Sigstore integration time:
-
Permalink:
jkeifer/ipynb-scrubber@03bcf89bfb16796575e2ff0b6e5d355b28412dd0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jkeifer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@03bcf89bfb16796575e2ff0b6e5d355b28412dd0 -
Trigger Event:
release
-
Statement type:
File details
Details for the file ipynb_scrubber-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ipynb_scrubber-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
232db5981bf438064a673f5569b4e0ea66efd967191071be50b4ee94bfbad39e
|
|
| MD5 |
acd87bed1cd654bae065aaa94aa7ae76
|
|
| BLAKE2b-256 |
f3cd44c319e27e43973d7437c52abc847f0a23bcf35fcf626e8fdf20c60869e3
|
Provenance
The following attestation bundles were made for ipynb_scrubber-0.1.0-py3-none-any.whl:
Publisher:
release.yml on jkeifer/ipynb-scrubber
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ipynb_scrubber-0.1.0-py3-none-any.whl -
Subject digest:
232db5981bf438064a673f5569b4e0ea66efd967191071be50b4ee94bfbad39e - Sigstore transparency entry: 428815791
- Sigstore integration time:
-
Permalink:
jkeifer/ipynb-scrubber@03bcf89bfb16796575e2ff0b6e5d355b28412dd0 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/jkeifer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@03bcf89bfb16796575e2ff0b6e5d355b28412dd0 -
Trigger Event:
release
-
Statement type: