Convert a Python repository into a single executable Jupyter notebook
Project description
rep2nb
Convert a Python repository into a single executable Jupyter notebook.
The problem: You built a well-structured repo with multiple files, proper separation of concerns, clean imports — then someone says "we need a .ipynb." You now have to manually copy-paste everything into cells, figure out the right order, inline your imports, and pray it runs.
The solution: One command.
rep2nb /path/to/your/repo -o submission.ipynb
rep2nb analyzes your repo's dependency graph, topologically sorts your files, and produces a single notebook where every cell runs in order — just like your repo does.
Installation
pip install rep2nb
From source
git clone https://github.com/tyephoenix/rep2nb.git
cd rep2nb
pip install .
Usage
CLI
# Auto-detect entry point, output to <repo-name>.ipynb
rep2nb myproject/
# Specify entry point and output file
rep2nb myproject/ --entry main.py -o submission.ipynb
# Exclude directories
rep2nb myproject/ --exclude tests/ --exclude docs/
# Add a pip install cell for external dependencies
rep2nb myproject/ --include-pip-install
# Multiple entry points in a specific order (e.g. generate data, then analyze it)
rep2nb myproject/ --entry generate.py --entry analyze.py
# Repo with multiple independent sub-projects (sections auto-detected)
rep2nb contest-repo/ --entry problem-1/pipeline.py --entry problem-2/main.py
# Disable auto-section detection
rep2nb myproject/ --no-sections
Python API
from rep2nb import convert
# Basic usage
convert("myproject/", output="submission.ipynb")
# With options
convert(
"myproject/",
output="submission.ipynb",
entry="main.py",
exclude=["tests/", "docs/"],
include_pip_install=True,
)
# Multiple entry points with explicit ordering
convert("myproject/", entry=["generate.py", "analyze.py"])
# Multi-project repo with section-specific entries
convert(
"contest-repo/",
entry=["problem-1/pipeline.py", "problem-2/main.py"],
output="submission.ipynb",
)
How It Works
- Discovery — finds all
.pyfiles, skippingvenv/,__pycache__/, etc. - Section Detection — subdirectories without
__init__.pyare treated as independent sections; packages stay in the root section - AST Analysis — parses each file to extract imports, definitions, docstrings, and
if __name__ == '__main__'blocks - Dependency Graph — builds a directed graph of which files import from which (per section)
- Topological Sort — determines the correct execution order (dependencies first)
- Transform — for each file:
- Library modules: strips
if __name__ == '__main__'test blocks, addssys.modulesregistration so imports resolve correctly - Entry points: unwraps
if __name__ == '__main__'so the code runs, resetssys.argvfor argparse compatibility - Relative imports (
from . import X) are rewritten to absolute form - Module-level docstrings are extracted and placed in markdown cells
- Library modules: strips
- Notebook Assembly — produces a valid
.ipynbwith:- README content as a markdown header (if found)
- A notice about required data files
- Optional
!pip installcell (uses kernel-safesys.executable) - Section headers and
os.chdirfor multi-project repos - Markdown cells with module docstrings above each code cell
sys.modulescleanup between sections to prevent name collisions
Features
- Dependency resolution — handles
import X,from X import Y, relative imports, and packages with__init__.py - Correct execution order — topological sort ensures definitions exist before use
- Cross-file imports just work — each module is registered in
sys.modules, so all import styles resolve correctly - Sections mode — independent subdirectories (e.g.
problem-1/,problem-2/) become isolated notebook sections withsys.modulescleanup between them, so files with the same name (likehelpers.py) don't collide - Docstring extraction — module-level docstrings become markdown cells above each code cell for readability; function/class docstrings stay in the code
- Smart entry point detection — auto-detects
main.py,app.py,pipeline.py,run.py, or files withif __name__ == '__main__'that nothing else imports - Argparse handling — resets
sys.argvin entry points soargparseuses defaults instead of crashing on Jupyter kernel args __file__support — injects__file__so scripts usingos.path.dirname(__file__)for relative paths still work- README at the top — your repo's README becomes the notebook's header
- Data file awareness — lists non-Python files that should be in the working directory
- Portable notebooks — zero absolute paths; the generated notebook can be moved anywhere (bring your data files)
- Zero config — works out of the box for typical repo structures
Limitations
- Python only — only converts
.pyfiles (notebooks run Python kernels) - Dynamic imports —
importlib.import_module(name)wherenameis a runtime value can't be detected statically - Subprocess calls — if your code shells out to other scripts, those won't be inlined
- Circular imports — detected and reported as an error (fix them in your repo first)
Development
git clone https://github.com/tyephoenix/rep2nb.git
cd rep2nb
pip install -e ".[dev]"
pytest
Requirements
- Python >= 3.10
nbformat(installed automatically)
License
MIT
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 rep2nb-0.1.0.tar.gz.
File metadata
- Download URL: rep2nb-0.1.0.tar.gz
- Upload date:
- Size: 19.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09002922274941a0bcc7089c64f8fc334b0fe28f29914844075354fa3cd114a2
|
|
| MD5 |
01136ac4f8326dc17a39aff9ea1f5596
|
|
| BLAKE2b-256 |
7fba1c4fda348d6158a1e817d5f8288f3694737b4ab142a7daa73a7a6631186c
|
File details
Details for the file rep2nb-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rep2nb-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54ff49f08c4e34aad8d5fa6678f038a31a498de48466cc511b292b87b8f4ab74
|
|
| MD5 |
ef59b56a4965c84e370a868d8de67ebf
|
|
| BLAKE2b-256 |
80c0f5921cbf1e27b9c163fbbb28ab000de36962d7a004a79bfc67498b0cbf01
|