sphinx-pyrepl-web

Sphinx extension to embed pyrepl-web in documentation.

Install

pip install sphinx-pyrepl-web

For development:

pip install -e ".[test,docs]"

Usage

Add the extension to the target project’s conf.py:

extensions = [
    "sphinx_pyrepl_web",
]

Embed a REPL with the py-repl directive:

.. py-repl::

.. py-repl::
   :theme: catppuccin-latte
   :no-header:

.. py-repl::
   :src: setup.py
   :packages: numpy

.. py-repl::
   :no-header:

   >>> import math
   >>> math.sqrt(16)

Directive options

All options drive pyrepl-web’s attributes, with the exception of silent:

Option

Description

:theme:

Color theme (catppuccin-mocha, catppuccin-latte)

:packages:

Comma-separated PyPI packages to preload

:repl-title:

Title in the REPL header

:src:

Path to a Python startup script

:replay:

Replay :src: with interactive prompts instead of silent load

:silent:

Keep :src: silent even when combined with a directive body

:no-header:

Hide the header bar

:no-buttons:

Hide copy/clear buttons

:readonly:

Disable input

:no-banner:

Hide the Python version banner

Python code within the .. py-repl:: directive is written to _static/pyrepl/ at build time and emitted as replay-src.

Optional Sphinx config:

pyrepl_js = "../pyrepl.js"  # default; path to the pyrepl-web loader script
pyrepl_doctest_blocks = False  # default; see Docstring conversion below
pyrepl_autodoc_bootstrap = True  # default; silent :src: bootstrap for autodoc REPLs

Docstring conversion

Converting doctest examples from docstrings into interactive REPLs is opt-in with sphinx.ext.autodoc:

# conf.py
extensions = [
    "sphinx.ext.autodoc",
    "sphinx_pyrepl_web",
]
pyrepl_doctest_blocks = "autodoc"

pyrepl_doctest_blocks options

False (default)

Disable autodoc conversion

"autodoc"

Convert doctests found by autodoc

"all"

Transform every doctest block found

pyrepl_autodoc_bootstrap options

True (default)

Bootstrap REPL: in-tree modules via silent :src:, packages via packages=

False

Replay doctest input only; documented names are not pre-defined

Updating pyrepl-web

Since chrizzFTD/pyrepl-web is a fork, this sphinx extension vendors the JavaScript assets for easier distribution. To update them, run:

python scripts/vendor_repl.py

The grill branch is used by default. Use the branch argument to specify a different one:

python scripts/vendor_repl.py --branch custom/feature-branch

This requires git and Bun.

Examples

Basic REPL

.. py-repl::

Light theme, minimal

.. py-repl::
   :theme: catppuccin-latte
   :no-header:
   :no-banner:

Startup script

The :src: option loads a Python script into the REPL namespace. If the script defines a setup() function, its output is shown when the REPL starts.

Startup script:

message = "Hello from the startup script!"


def setup():
    print(message)
    print("Try: message")

RST content:

.. py-repl::
   :src: _static/setup.py

Rendered result:

Replay session

Inline directive content should follow Doctest-style (>>> / ...) and is used as replay prompts.

.. py-repl::
   :no-header:
   :no-banner:

   >>> x = 2 + 2
   >>> print(f"{x=}")
   >>> x * 10
   >>> class Foo:
   ...     x = 1
   ...
   >>> Foo()

Combine a silent bootstrap file with a visible replay body:

.. py-repl::
   :src: _static/setup.py
   :no-header:

   >>> print(message)

Use :replay: on :src: to source a file as replay.

Source script:

greeting = "Hello from replay mode"
print(greeting)
greeting.upper()

RST content:

.. py-repl::
   :src: _static/replay_demo.py
   :replay:
   :no-header:
   :no-banner:

Rendered result:

Autodoc

The documented module’s source is loaded in advance before replay, so module members are available in the REPL namespace. Modules under the Sphinx source tree use silent :src:; installed packages use packages=.

Source module:

"""Demo module for autodoc doctest REPL integration."""

def example_generator(n):
    """Generators yield values useful for iteration.

    Example:

        >>> print([i for i in example_generator(4)])
        [0, 1, 2, 3]

    """
    yield from range(n)

RST content:

.. autofunction:: autodoc_demo.example_generator

Rendered result:

autodoc_demo.example_generator(n)

Generators yield values useful for iteration.

Example