Skip to main content

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',
    },
}
  • 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.
  • 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 to None to 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 as text url in .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 (or py) 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. "See Also" is recognized in any of its three forms (.. seealso::, a bare .. rubric:: See Also, or a hand-written See Also heading) and always renders the same way.
  • 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`). If html_baseurl is set and the reference resolves: .ipynb turns it into a clickable link everywhere; .py only writes the link inside a "See Also" part (as name url on its own line) — everywhere else in .py the 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 title-plus-underline treatment as the file's own header, 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: level 1 (<h1>, # Title + # ====) for the file's own header, or a cell heading that reuses the page title's own underline character; level 2 (<h2>, # Title + # ----) for a cell heading nested under it (the common case), or one level below whatever heading precedes it. Level 3 and deeper use ATX syntax instead (# ### Title), since Markdown's underline-style headings only support two levels.

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/.zip downloads 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.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sphinx-examples-as-code 0.3.1
File Size Uploaded
sphinx_examples_as_code-0.3.1.tar.gz 57.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sphinx-examples-as-code 0.3.1
File Interpreter ABI Platform
sphinx_examples_as_code-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 77.9 kB

Release files / sphinx_examples_as_code-0.3.1.tar.gz

Download URL sphinx_examples_as_code-0.3.1.tar.gz
Size 57.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7bd06c0a2b3310d1e0ab2170bd85e587e541da824415db317f535ba1e81b914f
BLAKE2b-256 checksum
How to use checksums
37c7e7aacd164a888df52c9e700483bbf7c230e03b4d6f704e6873c2a404e5b7
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 7, 2026.

Transparency log

Release files / sphinx_examples_as_code-0.3.1-py3-none-any.whl

Download URL sphinx_examples_as_code-0.3.1-py3-none-any.whl
Size 20.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
607dada8f7137c026a3235d76c19fa7e59f660432603ab5768e3e6e1e24ffb36
BLAKE2b-256 checksum
How to use checksums
d8bd60213cce83643a6920975d112831b2b443918d1afb230a8a2d770363a34c
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 7, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page