sphinx-exec-jupyter 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sphinx_exec_jupyter-0.1.0/.github/dependabot.yml +8 -0
- sphinx_exec_jupyter-0.1.0/.github/workflows/ci.yml +87 -0
- sphinx_exec_jupyter-0.1.0/.github/workflows/release.yml +24 -0
- sphinx_exec_jupyter-0.1.0/.gitignore +16 -0
- sphinx_exec_jupyter-0.1.0/.pre-commit-config.yaml +29 -0
- sphinx_exec_jupyter-0.1.0/.readthedocs.yml +15 -0
- sphinx_exec_jupyter-0.1.0/.taplo.toml +5 -0
- sphinx_exec_jupyter-0.1.0/.vscode/launch.json +30 -0
- sphinx_exec_jupyter-0.1.0/.vscode/settings.json +22 -0
- sphinx_exec_jupyter-0.1.0/PKG-INFO +20 -0
- sphinx_exec_jupyter-0.1.0/README.md +59 -0
- sphinx_exec_jupyter-0.1.0/biome.jsonc +18 -0
- sphinx_exec_jupyter-0.1.0/docs/conf.py +23 -0
- sphinx_exec_jupyter-0.1.0/docs/index.rst +122 -0
- sphinx_exec_jupyter-0.1.0/pyproject.toml +80 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/__init__.py +53 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/_directive.py +24 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/_kernel_mgr/__init__.py +264 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/_kernel_mgr/fork-server.py +78 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/_kernel_mgr/myst.py +52 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/common.py +80 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/holoviews/__init__.py +38 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/holoviews/_directive.py +129 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/holoviews/_mime_render.py +27 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/holoviews/collect-urls.py +19 -0
- sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/py.typed +0 -0
- sphinx_exec_jupyter-0.1.0/tests/test_extension.py +23 -0
- sphinx_exec_jupyter-0.1.0/tests/test_kernel_mgr.py +91 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
FORCE_COLOR: "1"
|
|
10
|
+
|
|
11
|
+
permissions: {}
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
15
|
+
cancel-in-progress: true
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
get-environments:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
outputs:
|
|
21
|
+
envs: ${{ steps.get-envs.outputs.envs }}
|
|
22
|
+
steps:
|
|
23
|
+
- &CLONE
|
|
24
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
|
25
|
+
with:
|
|
26
|
+
filter: blob:none
|
|
27
|
+
fetch-depth: 0
|
|
28
|
+
persist-credentials: false
|
|
29
|
+
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 #v8.2.0
|
|
30
|
+
with:
|
|
31
|
+
enable-cache: false
|
|
32
|
+
- id: get-envs
|
|
33
|
+
run: |
|
|
34
|
+
ENVS_JSON=$(NO_COLOR=1 uvx hatch env show --json | jq -c 'to_entries
|
|
35
|
+
| map(
|
|
36
|
+
select(.key | startswith("hatch-test"))
|
|
37
|
+
| { name: .key, python: .value.python }
|
|
38
|
+
)')
|
|
39
|
+
echo "envs=${ENVS_JSON}" | tee $GITHUB_OUTPUT
|
|
40
|
+
test:
|
|
41
|
+
needs: get-environments
|
|
42
|
+
permissions:
|
|
43
|
+
id-token: write # for codecov OIDC
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
strategy:
|
|
46
|
+
matrix:
|
|
47
|
+
env: ${{ fromJSON(needs.get-environments.outputs.envs) }}
|
|
48
|
+
env: # environment variable for use in codecov’s env_vars tagging
|
|
49
|
+
ENV_NAME: ${{ matrix.env.name }}
|
|
50
|
+
steps:
|
|
51
|
+
- *CLONE
|
|
52
|
+
- name: Install UV
|
|
53
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 #v8.2.0
|
|
54
|
+
- name: Install dependencies
|
|
55
|
+
run: uvx hatch -v env create ${{ matrix.env.name }}
|
|
56
|
+
- name: Run tests
|
|
57
|
+
run: |
|
|
58
|
+
uvx hatch run ${{ matrix.env.name }}:run-cov -v --color=yes -n auto --junitxml=test-results.xml
|
|
59
|
+
uvx hatch run ${{ matrix.env.name }}:cov-combine
|
|
60
|
+
uvx hatch run ${{ matrix.env.name }}:coverage xml
|
|
61
|
+
uvx hatch run ${{ matrix.env.name }}:cov-report
|
|
62
|
+
- name: Upload coverage data
|
|
63
|
+
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f #v7.0.0
|
|
64
|
+
with:
|
|
65
|
+
report_type: coverage
|
|
66
|
+
use_oidc: true
|
|
67
|
+
env_vars: ENV_NAME
|
|
68
|
+
fail_ci_if_error: true
|
|
69
|
+
- name: Upload test results
|
|
70
|
+
if: ${{ !cancelled() }}
|
|
71
|
+
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f #v7.0.0
|
|
72
|
+
with:
|
|
73
|
+
report_type: test_results
|
|
74
|
+
use_oidc: true
|
|
75
|
+
env_vars: ENV_NAME
|
|
76
|
+
fail_ci_if_error: true
|
|
77
|
+
files: test-results.xml
|
|
78
|
+
check:
|
|
79
|
+
if: always()
|
|
80
|
+
needs:
|
|
81
|
+
- get-environments
|
|
82
|
+
- test
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
steps:
|
|
85
|
+
- uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe #v1.2.2
|
|
86
|
+
with:
|
|
87
|
+
jobs: ${{ toJSON(needs) }}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Publish Python Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions: {}
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
publish:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
environment: pypi
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write # to authenticate as Trusted Publisher to pypi.org
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 #v6.3.0
|
|
20
|
+
with:
|
|
21
|
+
python-version: "3.x"
|
|
22
|
+
- run: pip install build
|
|
23
|
+
- run: python -m build
|
|
24
|
+
- uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b #v1.14.0
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
ci:
|
|
2
|
+
autoupdate_commit_msg: "ci: pre-commit autoupdate"
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
+
rev: v6.0.0
|
|
6
|
+
hooks:
|
|
7
|
+
- id: end-of-file-fixer
|
|
8
|
+
- id: trailing-whitespace
|
|
9
|
+
- id: no-commit-to-branch
|
|
10
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
11
|
+
rev: v0.15.18
|
|
12
|
+
hooks:
|
|
13
|
+
- id: ruff-check
|
|
14
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
15
|
+
- id: ruff-check
|
|
16
|
+
args: [--preview, --select=CPY]
|
|
17
|
+
- id: ruff-format
|
|
18
|
+
- repo: https://github.com/tox-dev/pyproject-fmt
|
|
19
|
+
rev: v2.25.0
|
|
20
|
+
hooks:
|
|
21
|
+
- id: pyproject-fmt
|
|
22
|
+
- repo: https://github.com/biomejs/pre-commit
|
|
23
|
+
rev: v2.5.0
|
|
24
|
+
hooks:
|
|
25
|
+
- id: biome-format
|
|
26
|
+
- repo: https://github.com/zizmorcore/zizmor-pre-commit
|
|
27
|
+
rev: v1.26.1
|
|
28
|
+
hooks:
|
|
29
|
+
- id: zizmor
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# https://docs.readthedocs.io/en/stable/config-file/v2.html
|
|
2
|
+
version: 2
|
|
3
|
+
build:
|
|
4
|
+
os: ubuntu-24.04
|
|
5
|
+
tools:
|
|
6
|
+
python: "3.13"
|
|
7
|
+
jobs:
|
|
8
|
+
create_environment:
|
|
9
|
+
- asdf plugin add uv
|
|
10
|
+
- asdf install uv latest
|
|
11
|
+
- asdf global uv latest
|
|
12
|
+
build:
|
|
13
|
+
html:
|
|
14
|
+
- uvx hatch run docs-build
|
|
15
|
+
- mv docs/_build $READTHEDOCS_OUTPUT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
// https://go.microsoft.com/fwlink/?linkid=830387
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"configurations": [
|
|
5
|
+
{
|
|
6
|
+
"name": "Build Documentation",
|
|
7
|
+
"type": "debugpy",
|
|
8
|
+
"request": "launch",
|
|
9
|
+
"python": "${command:hatch.envInterpreter}", //always default env
|
|
10
|
+
"module": "sphinx",
|
|
11
|
+
"args": ["-M", "html", ".", "_build"],
|
|
12
|
+
"cwd": "${workspaceFolder}/docs",
|
|
13
|
+
"console": "internalConsole",
|
|
14
|
+
"justMyCode": false,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "Debug test",
|
|
18
|
+
"type": "debugpy",
|
|
19
|
+
"request": "launch",
|
|
20
|
+
"program": "${file}",
|
|
21
|
+
"pythonArgs": ["-Xfrozen_modules=off"],
|
|
22
|
+
"console": "internalConsole",
|
|
23
|
+
"justMyCode": false,
|
|
24
|
+
"purpose": ["debug-test"],
|
|
25
|
+
"presentation": {
|
|
26
|
+
"hidden": true,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"[toml][json][jsonc][python]": {
|
|
3
|
+
"editor.formatOnSave": true,
|
|
4
|
+
},
|
|
5
|
+
"[toml]": {
|
|
6
|
+
"editor.defaultFormatter": "tamasfe.even-better-toml",
|
|
7
|
+
},
|
|
8
|
+
"[json][jsonc]": {
|
|
9
|
+
"editor.defaultFormatter": "biomejs.biome",
|
|
10
|
+
},
|
|
11
|
+
"[python]": {
|
|
12
|
+
"editor.defaultFormatter": "charliermarsh.ruff",
|
|
13
|
+
"editor.codeActionsOnSave": {
|
|
14
|
+
"source.fixAll": "explicit",
|
|
15
|
+
"source.organizeImports": "explicit",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
"python.testing.pytestEnabled": true,
|
|
19
|
+
"python.testing.pytestArgs": ["-vv", "--color=yes"],
|
|
20
|
+
"python-envs.defaultEnvManager": "pypa.hatch:hatch",
|
|
21
|
+
"python-envs.defaultPackageManager": "pypa.hatch:hatch",
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sphinx-exec-jupyter
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Execute code and let Jupyter format the output
|
|
5
|
+
Project-URL: Documentation, https://sphinx-exec-jupyter.readthedocs.io/
|
|
6
|
+
Project-URL: Source, https://github.com/flying-sheep/sphinx-exec-jupyter
|
|
7
|
+
Author-email: "Philipp A." <flying-sheep@web.de>
|
|
8
|
+
License-Expression: MPL-2.0
|
|
9
|
+
Classifier: Framework :: Sphinx :: Extension
|
|
10
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Requires-Dist: myst-nb>=1.4
|
|
16
|
+
Requires-Dist: nbformat>=5.10.4
|
|
17
|
+
Requires-Dist: sphinx>=9.1
|
|
18
|
+
Provides-Extra: holoviews
|
|
19
|
+
Requires-Dist: holoviews; extra == 'holoviews'
|
|
20
|
+
Requires-Dist: sphinx-design; extra == 'holoviews'
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# sphinx-exec-jupyter
|
|
2
|
+
|
|
3
|
+
[![Documentation Status][doc badge]][docs]
|
|
4
|
+
[![Test Status][test badge]][tests]
|
|
5
|
+
[![Coverage Status][codecov badge]][codecov]
|
|
6
|
+
|
|
7
|
+
[doc badge]: https://readthedocs.org/projects/sphinx-exec-jupyter/badge/
|
|
8
|
+
[docs]: https://sphinx-exec-jupyter.readthedocs.io/
|
|
9
|
+
[test badge]: https://github.com/flying-sheep/sphinx-exec-jupyter/actions/workflows/ci.yml/badge.svg
|
|
10
|
+
[tests]: https://github.com/flying-sheep/sphinx-exec-jupyter/actions/workflows/ci.yml
|
|
11
|
+
[codecov badge]: https://codecov.io/gh/flying-sheep/sphinx-exec-jupyter/branch/main/graph/badge.svg
|
|
12
|
+
[codecov]: https://codecov.io/gh/flying-sheep/sphinx-exec-jupyter
|
|
13
|
+
|
|
14
|
+
This Sphinx extension allows you to execute Jupyter notebooks and include their output in your documentation.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Install or depend on
|
|
19
|
+
`sphinx-exec-jupyter @ git+https://github.com/flying-sheep/sphinx-exec-jupyter.git`,
|
|
20
|
+
optionally with the `holoviews` extra (see below).
|
|
21
|
+
Then enable this extension in your `conf.py`:
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
extensions = [
|
|
25
|
+
"sphinx_exec_jupyter",
|
|
26
|
+
]
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Directives
|
|
30
|
+
|
|
31
|
+
### `exec-jupyter`
|
|
32
|
+
|
|
33
|
+
Executes a Jupyter notebook cell and includes its output:
|
|
34
|
+
|
|
35
|
+
```rst
|
|
36
|
+
.. exec-jupyter::
|
|
37
|
+
|
|
38
|
+
import numpy as np
|
|
39
|
+
np.random.rand(4)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `holoviews`
|
|
43
|
+
|
|
44
|
+
Enable by installing the `holoviews` extra by depending on
|
|
45
|
+
`sphinx-exec-jupyter[holoviews] @ git+https://github.com/flying-sheep/sphinx-exec-jupyter.git`
|
|
46
|
+
|
|
47
|
+
Embeds a HoloViews plot:
|
|
48
|
+
|
|
49
|
+
```rst
|
|
50
|
+
.. holoviews::
|
|
51
|
+
:backends: bokeh,matplotlib
|
|
52
|
+
|
|
53
|
+
hv.Curve([1, 2, 3, 2, 1])
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The default for `backends` is defined by a Sphinx `conf.py` setting:
|
|
57
|
+
`holoviews_backends = ['bokeh']`
|
|
58
|
+
|
|
59
|
+
For detailed documentation, visit [Read the Docs](https://sphinx-exec-jupyter.readthedocs.io/).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.1.1/schema.json",
|
|
3
|
+
"formatter": { "useEditorconfig": true },
|
|
4
|
+
"overrides": [
|
|
5
|
+
{
|
|
6
|
+
"includes": ["./.vscode/*.json", "**/*.jsonc"],
|
|
7
|
+
"json": {
|
|
8
|
+
"formatter": {
|
|
9
|
+
"trailingCommas": "all",
|
|
10
|
+
},
|
|
11
|
+
"parser": {
|
|
12
|
+
"allowComments": true,
|
|
13
|
+
"allowTrailingCommas": true,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
"""Configuration for Sphinx documentation."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from importlib.metadata import metadata
|
|
7
|
+
|
|
8
|
+
_meta = metadata("sphinx-exec-jupyter")
|
|
9
|
+
project = _meta["name"]
|
|
10
|
+
author = _meta["author-email"].split('"')[1]
|
|
11
|
+
release = _meta["version"]
|
|
12
|
+
|
|
13
|
+
extensions = [
|
|
14
|
+
"sphinx_exec_jupyter",
|
|
15
|
+
"sphinx_design",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
templates_path = ["_templates"]
|
|
19
|
+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
20
|
+
|
|
21
|
+
master_doc = "index"
|
|
22
|
+
|
|
23
|
+
html_theme = "furo"
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
``sphinx_exec_jupyter``
|
|
2
|
+
=======================
|
|
3
|
+
|
|
4
|
+
The ``sphinx-exec-jupyter`` Sphinx extension allows you to execute code
|
|
5
|
+
in a Jupyter kernel and embed the output directly into your Sphinx documentation.
|
|
6
|
+
|
|
7
|
+
This extension adds at least one directive (see `sphinx_exec_jupyter.holoviews`_ for more):
|
|
8
|
+
|
|
9
|
+
.. rst:directive:: exec-jupyter
|
|
10
|
+
|
|
11
|
+
Execute a Jupyter notebook cell and embed the output into the documentation.
|
|
12
|
+
The Python expression on the last line of the directive body is displayed.
|
|
13
|
+
|
|
14
|
+
It can be configured with the following settings:
|
|
15
|
+
|
|
16
|
+
.. confval:: exec_jupyter_code
|
|
17
|
+
:type: ``str``
|
|
18
|
+
|
|
19
|
+
Prefix code to execute before the code in ``exec-jupyter`` or ``holoviews``.
|
|
20
|
+
Kernels are started from forked processes after this code is executed,
|
|
21
|
+
so it can be used for long-running initialization code (e.g. slow imports).
|
|
22
|
+
|
|
23
|
+
.. confval:: exec_jupyter_kernel
|
|
24
|
+
:type: ``str``
|
|
25
|
+
|
|
26
|
+
Name of the Jupyter kernel to use.
|
|
27
|
+
If not set, the default kernel is used.
|
|
28
|
+
|
|
29
|
+
.. confval:: exec_jupyter_patch_myst_nb
|
|
30
|
+
:type: ``bool``
|
|
31
|
+
|
|
32
|
+
If ``True`` (the default), and either ``exec_jupyter_code`` or ``exec_jupyter_kernel`` are set,
|
|
33
|
+
the ``myst_nb`` extension is patched to use the provided code and/or kernel.
|
|
34
|
+
|
|
35
|
+
Examples
|
|
36
|
+
--------
|
|
37
|
+
|
|
38
|
+
.. code-block:: rst
|
|
39
|
+
|
|
40
|
+
.. exec-jupyter::
|
|
41
|
+
|
|
42
|
+
import pandas as pd
|
|
43
|
+
|
|
44
|
+
pd.DataFrame(dict(
|
|
45
|
+
A=[1, 2, 3],
|
|
46
|
+
B=[4, 5, 6],
|
|
47
|
+
))
|
|
48
|
+
|
|
49
|
+
results in:
|
|
50
|
+
|
|
51
|
+
.. exec-jupyter::
|
|
52
|
+
|
|
53
|
+
import pandas as pd
|
|
54
|
+
|
|
55
|
+
pd.DataFrame(dict(
|
|
56
|
+
A=[1, 2, 3],
|
|
57
|
+
B=[4, 5, 6],
|
|
58
|
+
))
|
|
59
|
+
|
|
60
|
+
``sphinx_exec_jupyter.holoviews``
|
|
61
|
+
---------------------------------
|
|
62
|
+
|
|
63
|
+
If you installed ``sphinx-exec-jupyter`` with the ``holoviews`` extra
|
|
64
|
+
(e.g. ``pip install sphinx-exec-jupyter[holoviews]``),
|
|
65
|
+
the ``sphinx_exec_jupyter.holoviews`` sub-extension is loaded automatically.
|
|
66
|
+
|
|
67
|
+
This extension adds a setting and one more directive:
|
|
68
|
+
|
|
69
|
+
.. confval:: holoviews_backends
|
|
70
|
+
:type: ``list[str]``
|
|
71
|
+
:default: ``['bokeh']``
|
|
72
|
+
|
|
73
|
+
A list of backends to use for rendering HoloViews plots.
|
|
74
|
+
|
|
75
|
+
.. rst:directive:: holoviews
|
|
76
|
+
|
|
77
|
+
Embed a HoloViews plot into the documentation.
|
|
78
|
+
The Python expression on the last line of the directive body is displayed.
|
|
79
|
+
|
|
80
|
+
.. rst:directive:option:: backends: backend1,backend2,...
|
|
81
|
+
:type: comma separated list of backends
|
|
82
|
+
|
|
83
|
+
The list of backends to use for rendering the plot. Defaults to :confval:`holoviews_backends`.
|
|
84
|
+
|
|
85
|
+
..
|
|
86
|
+
See here for syntax:
|
|
87
|
+
https://www.sphinx-doc.org/en/master/usage/domains/restructuredtext.html#directive-rst-directive
|
|
88
|
+
|
|
89
|
+
.. _holoviews-examples:
|
|
90
|
+
|
|
91
|
+
Examples
|
|
92
|
+
--------
|
|
93
|
+
|
|
94
|
+
No options (defaults to bokeh):
|
|
95
|
+
|
|
96
|
+
.. code-block:: rst
|
|
97
|
+
|
|
98
|
+
.. holoviews::
|
|
99
|
+
|
|
100
|
+
hv.Curve([1, 2, 3, 2, 1])
|
|
101
|
+
|
|
102
|
+
results in:
|
|
103
|
+
|
|
104
|
+
.. holoviews::
|
|
105
|
+
|
|
106
|
+
hv.Curve([1, 2, 3, 2, 1])
|
|
107
|
+
|
|
108
|
+
With multiple backends specified (needs the ``sphinx_design`` extension to be loaded):
|
|
109
|
+
|
|
110
|
+
.. code-block:: rst
|
|
111
|
+
|
|
112
|
+
.. holoviews::
|
|
113
|
+
:backends: bokeh,matplotlib,plotly
|
|
114
|
+
|
|
115
|
+
hv.Curve([1, 2, 3, 2, 1])
|
|
116
|
+
|
|
117
|
+
results in:
|
|
118
|
+
|
|
119
|
+
.. holoviews::
|
|
120
|
+
:backends: bokeh,matplotlib,plotly
|
|
121
|
+
|
|
122
|
+
hv.Curve([1, 2, 3, 2, 1])
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "hatchling.build"
|
|
3
|
+
requires = [ "hatch-vcs", "hatchling" ]
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sphinx-exec-jupyter"
|
|
7
|
+
description = "Execute code and let Jupyter format the output"
|
|
8
|
+
license = "MPL-2.0"
|
|
9
|
+
authors = [ { name = "Philipp A.", email = "flying-sheep@web.de" } ]
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Framework :: Sphinx :: Extension",
|
|
13
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Programming Language :: Python :: 3.13",
|
|
16
|
+
"Programming Language :: Python :: 3.14",
|
|
17
|
+
]
|
|
18
|
+
dynamic = [ "version" ]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"myst-nb>=1.4",
|
|
21
|
+
"nbformat>=5.10.4",
|
|
22
|
+
"sphinx>=9.1",
|
|
23
|
+
]
|
|
24
|
+
optional-dependencies.holoviews = [ "holoviews", "sphinx-design" ]
|
|
25
|
+
urls.Documentation = "https://sphinx-exec-jupyter.readthedocs.io/"
|
|
26
|
+
urls.Source = "https://github.com/flying-sheep/sphinx-exec-jupyter"
|
|
27
|
+
entry-points."jupyter_client.kernel_provisioners".forking_provisioner = "sphinx_exec_jupyter._kernel_mgr:ForkingProvisioner"
|
|
28
|
+
entry-points."myst_nb.mime_renderers".holoviews = "sphinx_exec_jupyter.holoviews:HoloViewsMimeRenderer"
|
|
29
|
+
|
|
30
|
+
[tool.hatch]
|
|
31
|
+
version.source = "vcs"
|
|
32
|
+
envs.default.installer = "uv"
|
|
33
|
+
envs.default.features = [ "holoviews" ]
|
|
34
|
+
envs.default.dependencies = [ "furo", "matplotlib", "plotly" ]
|
|
35
|
+
envs.default.scripts.docs-build = "sphinx-build -M html docs docs/_build {args:-W}"
|
|
36
|
+
envs.default.scripts.docs-clean = "rm -rf docs/_build {args}"
|
|
37
|
+
envs.default.scripts.docs-open = "python -m webbrowser docs/_build/html/index.html {args}"
|
|
38
|
+
envs.hatch-test.features = [ "holoviews" ]
|
|
39
|
+
envs.hatch-test.extra-dependencies = [ "anyio", "nbformat-types", "pytest-mock" ]
|
|
40
|
+
envs.hatch-test.matrix = [
|
|
41
|
+
{ python = [ "3.14", "3.12" ] },
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[tool.ruff]
|
|
45
|
+
lint.select = [ "ALL" ]
|
|
46
|
+
lint.ignore = [
|
|
47
|
+
"C408", # `dict()` is fine
|
|
48
|
+
"COM812", # conflict with formatter
|
|
49
|
+
"D203",
|
|
50
|
+
"D213",
|
|
51
|
+
"N999", # Intentional dash in scripts not used for import
|
|
52
|
+
"S101", # `assert` is fine
|
|
53
|
+
"TID252", # relative imports preferred
|
|
54
|
+
]
|
|
55
|
+
lint.per-file-ignores."**/*-*" = [
|
|
56
|
+
"PLC0415", # imports are not at the top for a reason
|
|
57
|
+
"T201", # `print()` used for communication
|
|
58
|
+
]
|
|
59
|
+
lint.per-file-ignores."docs/**/*" = [ "INP001" ]
|
|
60
|
+
lint.per-file-ignores."src/**/*" = [ "PT018" ]
|
|
61
|
+
lint.per-file-ignores."tests/**/*" = [ "D", "INP001" ]
|
|
62
|
+
lint.allowed-confusables = [ "×", "’" ]
|
|
63
|
+
lint.flake8-copyright.notice-rgx = "SPDX-License-Identifier: MPL-2\\.0"
|
|
64
|
+
lint.flake8-type-checking.exempt-modules = []
|
|
65
|
+
lint.flake8-type-checking.strict = true
|
|
66
|
+
lint.isort.required-imports = [ "from __future__ import annotations" ]
|
|
67
|
+
|
|
68
|
+
[tool.pytest]
|
|
69
|
+
addopts = [
|
|
70
|
+
"--import-mode=importlib",
|
|
71
|
+
"--doctest-modules",
|
|
72
|
+
"--pyargs",
|
|
73
|
+
]
|
|
74
|
+
anyio_mode = "auto"
|
|
75
|
+
filterwarnings = [ "error" ]
|
|
76
|
+
strict = true
|
|
77
|
+
|
|
78
|
+
[tool.coverage]
|
|
79
|
+
run.patch = [ "subprocess" ]
|
|
80
|
+
run.source = [ "." ]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
"""Sphinx extension to run code snippets using Jupyter machinery."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from contextlib import suppress
|
|
7
|
+
from importlib.metadata import version
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from sphinx.errors import ExtensionError
|
|
11
|
+
from sphinx.util.typing import ExtensionMetadata
|
|
12
|
+
|
|
13
|
+
from ._directive import ExecJupyterDirective
|
|
14
|
+
from ._kernel_mgr import maybe_patch_myst_nb
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from sphinx.application import Sphinx
|
|
18
|
+
from sphinx.config import Config
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
__all__ = ["ExecJupyterDirective", "setup"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
25
|
+
"""Add directive(s) and settings to Sphinx."""
|
|
26
|
+
app.setup_extension("myst_nb")
|
|
27
|
+
app.add_config_value("exec_jupyter_code", "", "env")
|
|
28
|
+
app.add_config_value("exec_jupyter_kernel", "python3", "env")
|
|
29
|
+
app.add_config_value("exec_jupyter_patch_myst_nb", True, "env") # noqa: FBT003
|
|
30
|
+
app.add_directive("exec-jupyter", ExecJupyterDirective)
|
|
31
|
+
app.connect("config-inited", _maybe_patch_myst_nb)
|
|
32
|
+
|
|
33
|
+
with suppress(ExtensionError):
|
|
34
|
+
app.setup_extension("sphinx_exec_jupyter.holoviews")
|
|
35
|
+
|
|
36
|
+
return ExtensionMetadata(
|
|
37
|
+
version=version("sphinx-exec-jupyter"),
|
|
38
|
+
parallel_read_safe=True,
|
|
39
|
+
parallel_write_safe=True,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _maybe_patch_myst_nb(app: Sphinx, config: Config) -> None:
|
|
44
|
+
ctx = maybe_patch_myst_nb(config)
|
|
45
|
+
ctx.__enter__()
|
|
46
|
+
|
|
47
|
+
def cleanup(app: Sphinx, exc: Exception | None) -> None: # noqa: ARG001
|
|
48
|
+
if exc is None:
|
|
49
|
+
ctx.__exit__(None, None, None)
|
|
50
|
+
else:
|
|
51
|
+
ctx.__exit__(type(exc), exc, exc.__traceback__)
|
|
52
|
+
|
|
53
|
+
app.connect("build-finished", cleanup)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from sphinx.util.docutils import SphinxDirective
|
|
7
|
+
|
|
8
|
+
from ._kernel_mgr import maybe_patch_myst_nb
|
|
9
|
+
from .common import execute_cells
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from docutils import nodes
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
__all__ = ["ExecJupyterDirective"]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ExecJupyterDirective(SphinxDirective):
|
|
19
|
+
has_content = True
|
|
20
|
+
|
|
21
|
+
def run(self) -> list[nodes.Node]:
|
|
22
|
+
code = "\n".join(self.content)
|
|
23
|
+
with maybe_patch_myst_nb(self.config):
|
|
24
|
+
return execute_cells([code], self.state.document)
|