sphinx-pyrepl-web¶
Sphinx extension to embed pyrepl-web in documentation.
Install¶
pip install sphinx-pyrepl-web
Usage¶
Add the extension to the target project’s conf.py module:
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:
Option |
Description |
|---|---|
|
Color theme ( |
|
Comma-separated PyPI packages, URLs or relative wheel paths |
|
Title in the REPL header |
|
Path to a Python startup script |
|
Replay |
|
Hide the header bar |
|
Hide copy/clear buttons |
|
Disable input |
|
Hide the Python version banner |
Sphinx options¶
Enable doctest style examples conversion into pre-configured interactive REPLs with:
pyrepl_doctest_blocks:
Value |
Outcome |
|---|---|
|
Don’t convert doctest blocks |
|
Convert doctest blocks from |
|
Convert all doctest blocks |
pyrepl_autodoc_packages:
Value |
Outcome |
|---|---|
|
Replay doctest input without preloading packages |
|
Build a wheel from the documented project and preload it |
Wheel path / PyPI names |
Install the package and import the documented object before replay |
Optional when using :project::
Value |
Default |
Outcome |
|---|---|---|
|
auto-detect |
Project root containing |
|
|
Directory for the built wheel, relative to |
Local wheels¶
Unreleased package wheels can be available in the REPL by building them under Sphinx’s html_static_path, or by using :project: to build automatically at doc-build time.
All options combined:
extensions = [
"sphinx.ext.autodoc",
"sphinx_pyrepl_web",
]
html_static_path = ["_static"]
pyrepl_doctest_blocks = "autodoc"
pyrepl_autodoc_packages = ":project:"
For a monorepo or non-default layout, point at the package root explicitly:
pyrepl_autodoc_packages = ":project:"
pyrepl_project_root = ".."
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 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 startup script 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:
Local packages¶
Use static local wheel packages on .. py-repl:: directives:
.. py-repl::
:packages: _static/wheels/pyrepl_test_pkg-1.0.0-py3-none-any.whl
:no-header:
:no-banner:
>>> import pyrepl_test_pkg
>>> pyrepl_test_pkg.ping()
Autodoc¶
Use pyrepl_doctest_blocks = "autodoc" to turn docstrings from autodoc into interactive REPL examples.
Set pyrepl_autodoc_packages to install the documented package and automatically import the documented object before replay:
# conf.py
html_static_path = ["_static"]
pyrepl_doctest_blocks = "autodoc"
pyrepl_autodoc_packages = ":project:"
pyrepl_project_root = "../tests/fixtures/pyrepl_test_pkg"
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:: pyrepl_test_pkg.demo.example_generator
Rendered result:
- pyrepl_test_pkg.demo.example_generator(n)¶
Generators yield values useful for iteration.
Example
Development¶
Setup¶
Clone the repository, then install in editable mode with test and docs dependencies,
plus the local pyrepl_test_pkg fixture used in the examples:
pip install -e ".[test,docs]"
pip install -e tests/fixtures/pyrepl_test_pkg
The [docs] extra pulls in doc build dependencies only (myst-parser).
The fixture package is installed separately because PyPI packages cannot declare
local path dependencies.
Build and preview docs¶
Build HTML output from the docs/ directory:
python -m sphinx -b html docs docs/_build
REPLs load JavaScript, replay scripts, and wheels with fetch, so they do not
work when opening index.html directly from disk (file:// URLs). Serve the
build output over HTTP instead:
python -m http.server --directory docs/_build
Then open http://localhost:8000/ in a browser.
Build-time behavior¶
Python code within a .. py-repl:: directive is written to _static/pyrepl/
at build time and emitted as replay-src.
File paths identifiers in :packages:, :src:, replay-src, and
pyrepl_autodoc_packages are rewritten to page-relative URLs so REPLs work on
nested pages (for example docs/api/...). PyPI package names, absolute URLs,
and paths written as root-absolute (/_static/...) are left unchanged.
pyrepl_js (default: "../pyrepl.js") sets the loader script Sphinx injects
on REPL pages. The extension vendors and copies pyrepl-web automatically;
override this only when pointing at a custom loader path or CDN.
Static wheels¶
Wheel packages must be Pyodide compatible (pure-python packages work out of the box).
For CPython extensions, visit pyodide-build.
Set pyrepl_autodoc_packages = ":project:" to build a wheel from the documented
project automatically during the Sphinx HTML build. The wheel is written to
_static/wheels/ (configurable via pyrepl_wheel_dir) and reused on
incremental builds until project sources change.
Wheels under _static/ are copied into the HTML output when _static is
listed in html_static_path. At runtime, pyrepl-web
resolves site-relative wheel paths to absolute URLs before calling
micropip.install().
Paths must use the wheel’s actual PyPI-compliant filename (for example
myext-1.2.3-py3-none-any.whl). micropip rejects other names.
Ensure the web server serves .whl files with MIME type application/zip
(Read the Docs does this by default).
Updating pyrepl-web¶
This extension vendors JavaScript from pyrepl-web’s fork for easier distribution. To refresh the vendored assets:
python scripts/vendor_repl.py
The grill branch is used by default. Pass --branch to vendor from another
branch:
python scripts/vendor_repl.py --branch custom/feature-branch