sphinx-examples-as-code
A Sphinx extension that turns docstring/page "Examples" sections into downloadable,
runnable .py and/or .ipynb files, with a download link inserted into the section.
Pages or docstrings without an Examples section are left completely untouched. Adding
sphinx_examples_as_code to conf.py's extensions is the only on/off switch.
Installation
pip install sphinx-examples-as-code
Add it to your Sphinx conf.py:
extensions = [
...,
'sphinx_examples_as_code',
]
Configuration
Everything lives in one dict in conf.py, sphinx_examples_as_code_conf -- set only
the keys you want to change from their default:
sphinx_examples_as_code_conf = {
'link_position': 'top',
'formats': ['py', 'ipynb'],
'gallery_downloads': False,
'footer': (
'Generated by `sphinx-examples-as-code '
'<https://github.com/pyvista/sphinx-examples-as-code>`_'
),
'link_labels': {
'py': 'Download Python source code',
'ipynb': 'Download Jupyter notebook',
},
'include_see_also': True,
}
link_position: where the download link(s) land within the Examples section.'top'(default) or'bottom'.formats: which downloads to generate. A list containing'py','ipynb', or both (default). Always offered in that order regardless of how the list is written.link_labels: the text of the download link(s) themselves, per format. Set only the format(s) you want to change; any left unset keep reading their own default shown above.include_see_also: whether "See Also" content is included in the generated file.True(default) includes it, in any of its forms: a.. seealso::admonition, a bare.. rubric:: See Also, a hand-writtenSee Alsoheading, or numpydoc's own "See Also" field (including when it's been reordered outside the Examples section itself, or the Examples section has been hoisted to a heading of its own — a setup some projects use to get "Examples" listed in the page's own navigation).Falseexcludes "See Also" content in every one of those forms.gallery_downloads: opt-in takeover of sphinx-gallery's own per-example downloads.False(default) leaves sphinx-gallery pages untouched. See Sphinx-Gallery integration below.footer: a string appended to the end of every generated file. Defaults to a one-line "generated file" credit linking back to this project; set toNoneto omit it entirely. Preceded by a blank line and a--only divider line, which also renders as a real horizontal rule in.ipynb; the footer always gets its own dedicated cell there. Parsed as RST: a hyperlink written as`text <url>`_becomes a real clickable Markdown link in.ipynb, and renders inline astext urlin.py. Plain text with no markup at all becomes one comment line per line of text, and blank-line-separated paragraphs stay separated.
An unrecognized key raises a configuration error at build start.
Cross-references and hyperlinks resolve into absolute links using Sphinx's own
html_baseurl.
Leave it unset and no links are generated anywhere.
Overriding a single key from the command line works via a dotted -D flag, e.g.
-D sphinx_examples_as_code_conf.link_position=bottom -- this only touches that one
key, leaving the rest (conf.py's values, or the defaults) alone.
Conversion rules
What happens to the content of an Examples section:
- Doctest blocks (
>>> .../... ...) keep their input lines, prompts stripped, as real Python source. Doctest output lines are dropped — only the input code matters. .. code-block:: python(orpy) blocks are kept as-is; other languages become comments, set off with blank lines on both sides like any other directive.- Admonitions (
.. note::,.. warning::,.. seealso::, ...) become a# LABEL:comment followed by their content as comments, indented one level under the label in.pyonly. "See Also" is recognized in any of its three forms (.. seealso::, a bare.. rubric:: See Also, or a hand-writtenSee Alsoheading) and always renders the same way. - A bullet/numbered list becomes a
-/N.-marked line per item, set off with a blank line on both sides in either format — a bare#instead of a real blank line when that falls inside an admonition or a definition's own body in.py, so the whole thing still reads as one unbroken comment block. A definition list's term stays at the surrounding indent; its definition (the body nested under it) is indented one level further in.py, same as an admonition's own content. - Cross-references and inline code (
:class:,:meth:,:func:,:attr:, double-backtick literals, ...) keep their display text, wrapped in backticks (e.g.:class:`pyvista.Plotter`->`pyvista.Plotter`). Ifhtml_baseurlis set and the reference resolves:.ipynbturns it into a clickable link everywhere;.pyonly writes the link inside a "See Also" part (asname urlon its own line) — everywhere else in.pythe link is simply omitted. - Plain prose-style references (
:ref:,:doc:) are treated the same way, minus the backticks. - Everything else text-bearing (prose, captions, other non-Python code) becomes a plain
#comment. - Figures/images, raw HTML, sphinx-design dropdowns/tab-sets, and sphinx-tags'
.. tags::line are dropped entirely.
Generated .py files start with a # Examples from <qualified name> title header
(gallery mode uses the page's own title instead -- see below), with a few whitespace
conventions: prose directly above a code block stays attached to it, a code block is
always followed by a blank line, and a directive (header, # NOTE:-style block) gets
blank lines on both sides.
Generated .ipynb notebooks use the same content, split into alternating code/markdown
cells instead.
A download link is only added if the resulting code contains at least one real executable statement.
Sphinx-Gallery integration
With sphinx_examples_as_code_conf['gallery_downloads'] = True, this extension takes
over the downloads on every page generated by
sphinx-gallery: the "Go to the end to download the
full example code" note and the .py/.ipynb/.zip download footer are removed from
the page, replaced with download link(s) built by this extension instead — same
conversion rules as above, applied to the whole page rather than one Examples section.
The generated file's header uses the page's own title (e.g. # Create Circular Arcs)
rather than the generic # Examples from <docname>.
The "Total running time" line and the "Gallery generated by Sphinx-Gallery" credit line stay on the rendered page untouched, but never make it into the generated download itself.
Detection is automatic and per-page — any page without a sphinx-gallery download footer is left completely untouched. Gallery pages and ordinary docstring/prose pages (using the Examples-section behavior above) can coexist on the same site.
A # %% cell with its own RST heading gets the same header treatment as the file's own
title, and renders as a real Markdown heading in .ipynb. Level is relative to actual
RST section nesting, not always one below the file's own header: a cell heading nested
under the page's own title (the common case) is one level below it; one that reuses the
page title's own underline character is level 1, the same as the file's own header; a
cell heading nested under that is level 2 relative to it, and so on.
Each format uses one heading style consistently across every level, rather than mixing styles:
.pyuses an RST-style title + underline, one character per level -- the same sequence Sphinx's own documentation uses for sections through sub-paragraphs:=,-,~,^,",'for levels 1 through 6..ipynbalways uses ATX syntax (#,##,###, ...) at every level.
Two things worth knowing before turning this on:
- It's built against sphinx-gallery's own RST/HTML output (the same
sphx-glr-*CSS classes its own theming depends on), not a documented extension API. A future sphinx-gallery release could shift that structure without warning. - sphinx-gallery's own
.py/.ipynb/.zipdownloads still end up copied into_downloads/, even though nothing on the page links to them anymore.
Development
uv sync --group dev
uv run pytest
uv run pre-commit run --all-files
Metadata
Release files for sphinx-examples-as-code 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sphinx_examples_as_code-0.4.1.tar.gz | 62.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sphinx_examples_as_code-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 83.5 kB
Release files / sphinx_examples_as_code-0.4.1.tar.gz
| Download URL | sphinx_examples_as_code-0.4.1.tar.gz |
|---|---|
| Size | 62.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2883021747a2faec73965ba0e3ba0c791ceb7a94514813d5970352391c695c69
|
|
BLAKE2b-256 checksum How to use checksums |
4c0867cf6dc8ef2881d495656a1562867a5e2a2fc0f0c86d631311d1ca4adf7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.
Transparency logRelease files / sphinx_examples_as_code-0.4.1-py3-none-any.whl
| Download URL | sphinx_examples_as_code-0.4.1-py3-none-any.whl |
|---|---|
| Size | 21.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f0f213c12b2ac9c9874b5b6b179d9a19fc41ffcae1114d83e44b77a410ed6229
|
|
BLAKE2b-256 checksum How to use checksums |
e1b476a254f4034c8893e6f2a4b7b220bd1ed9e658f3ead01c96306d07d32a5a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.
Transparency log