Skip to main content

rep2nb

CI PyPI version Python License: MIT

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

  1. Discovery — finds all .py files, skipping venv/, __pycache__/, etc.
  2. Section Detection — subdirectories without __init__.py are treated as independent sections; packages stay in the root section
  3. AST Analysis — parses each file to extract imports, definitions, docstrings, and if __name__ == '__main__' blocks
  4. Dependency Graph — builds a directed graph of which files import from which (per section)
  5. Topological Sort — determines the correct execution order (dependencies first)
  6. Transform — for each file:
    • Library modules: strips if __name__ == '__main__' test blocks, adds sys.modules registration so imports resolve correctly
    • Entry points: unwraps if __name__ == '__main__' so the code runs, resets sys.argv for argparse compatibility
    • Relative imports (from . import X) are rewritten to absolute form
    • Module-level docstrings are extracted and placed in markdown cells
  7. Notebook Assembly — produces a valid .ipynb with:
    • README content as a markdown header (if found)
    • A notice about required data files
    • Optional !pip install cell (uses kernel-safe sys.executable)
    • Section headers and os.chdir for multi-project repos
    • Markdown cells with module docstrings above each code cell
    • sys.modules cleanup 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 with sys.modules cleanup between them, so files with the same name (like helpers.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 with if __name__ == '__main__' that nothing else imports
  • Argparse handling — resets sys.argv in entry points so argparse uses defaults instead of crashing on Jupyter kernel args
  • __file__ support — injects __file__ so scripts using os.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 .py files (notebooks run Python kernels)
  • Dynamic imports — importlib.import_module(name) where name is 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

Release files for rep2nb 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rep2nb 0.1.0
File Size Uploaded
rep2nb-0.1.0.tar.gz 19.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rep2nb 0.1.0
File Interpreter ABI Platform
rep2nb-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 37.6 kB

Release files / rep2nb-0.1.0.tar.gz

Download URL rep2nb-0.1.0.tar.gz
Size 19.3 kB
Tags Source
SHA-256 checksum
How to use checksums
09002922274941a0bcc7089c64f8fc334b0fe28f29914844075354fa3cd114a2
BLAKE2b-256 checksum
How to use checksums
7fba1c4fda348d6158a1e817d5f8288f3694737b4ab142a7daa73a7a6631186c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.0

Release files / rep2nb-0.1.0-py3-none-any.whl

Download URL rep2nb-0.1.0-py3-none-any.whl
Size 18.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
54ff49f08c4e34aad8d5fa6678f038a31a498de48466cc511b292b87b8f4ab74
BLAKE2b-256 checksum
How to use checksums
80c0f5921cbf1e27b9c163fbbb28ab000de36962d7a004a79bfc67498b0cbf01
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.0

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page