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 |
|---|---|
|
Color theme ( |
|
Comma-separated PyPI packages or local wheel paths under |
|
Title in the REPL header |
|
Path to a Python startup script |
|
Replay |
|
Keep |
|
Hide the header bar |
|
Hide copy/clear buttons |
|
Disable input |
|
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.
File paths in :packages:, :src:, replay-src, and pyrepl_autodoc_packages are rewritten to page-relative URLs at build time so REPLs work on nested pages (for example docs/api/...). PyPI package names, absolute URLs, and paths you write as root-absolute (/_static/...) are left unchanged.
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_packages = None # optional; wheel path or PyPI name 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_autodoc_packages = "_static/wheels/my_package-1.0.0-py3-none-any.whl"
|
|
|---|---|
|
Disable autodoc conversion |
|
Convert doctests found by autodoc |
|
Transform every doctest block found |
|
|
|---|---|
unset / |
Replay doctest input only (no wheel install or auto-import) |
wheel path or PyPI name |
Install the package and import the documented object before replay (comma-separated) |
Autodoc integration assumes a single documented package. The wheel (or PyPI name) is installed in the browser REPL and the documented name is imported automatically so doctest examples can use unqualified names. Autodoc still imports the package on the host at build time.
To build this project’s docs locally:
pip install -e ".[docs]"
The [docs] extra installs doc build dependencies plus the pyrepl_test_pkg
fixture used in the examples.
Local Pyodide wheels¶
Preload a wheel built for Pyodide (for example a wasm extension or an unreleased
branch build) by placing it under the Sphinx static path and referencing it from
:packages:. Ensure html_static_path includes "_static":
# conf.py
html_static_path = ["_static"]
.. py-repl::
:packages: _static/wheels/myext-pyodide.whl
:src: _static/bootstrap.py
:no-banner:
>>> import myext
>>> myext.ping()
Wheels under _static/ are copied into the HTML output when _static is listed
in html_static_path (Sphinx does not copy project static files automatically
unless configured). At runtime, pyrepl-web
resolves site-relative wheel paths to absolute URLs before calling
micropip.install().
CI tip: copy each build artifact to a stable docs filename so RST does not
need updating per release, for example
cp dist/myext-1.2.3-*.whl docs/_static/wheels/myext-pyodide.whl.
Ensure the web server serves .whl files with MIME type application/zip
(Read the Docs does this by default).
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
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¶
When pyrepl_doctest_blocks = "autodoc", doctest examples in documented
APIs become interactive REPLs. Set pyrepl_autodoc_packages to install the
documented package from a Pyodide-compatible wheel (or PyPI name) and
automatically import the documented object before replay:
# conf.py
html_static_path = ["_static"]
pyrepl_autodoc_packages = "_static/wheels/pyrepl_test_pkg-1.0.0-py3-none-any.whl"
Autodoc still imports the package on the host at build time (for example via
pip install -e ".[docs]" in this repository).
Source module:
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
Local Pyodide wheels¶
The same wheel can be referenced manually from .. py-repl:: when you want
a standalone REPL without autodoc:
.. 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()