sphinxcontrib.datatemplates — Render Your Data Readable

sphinxcontrib.datatemplates helps you use static data in machine readable format in your documentation by letting you define Jinja2 templates to turn JSON, YAML, XML, or CSV data into reStructuredText for Sphinx to render as part of its output.

Using datatemplate

The datatemplate directive is the interface between the data source and the rendering template.

.. datatemplate:json:: source-path

Load file at source-path (relative to the documentation build directory) via json.load() and render using template given in directive body.

.. datatemplate:yaml:: source-path

Load file at source-path (relative to the documentation build directory) via PyYAML (yaml.safe_load) and render using template given in directive body.

.. datatemplate:xml:: source-path

Load file at source-path (relative to the documentation build directory) via xml.etree.ElementTree.parse() (actually using defusedxml) and render using template given in directive body.

.. datatemplate:import-module:: module-name

Load module module-name (must be importable in conf.py) via importlib.import_module() and render using template given in directive body.

.. datatemplate:csv:: source-path

Load file at source-path (relative to the documentation build directory) via csv.reader() or csv.DictReader depending on header and render using template given in directive body.

.. datatemplate:dbm:: source-path::

Load DB at source-path (relative to the documentation build directory) via dbm.open() and render using template given in directive body.

Template Context

When a datatemplate directive is processed, the data is passed to the template through its context so that the symbol data is available as a global variable.

Important

The data is loaded from the source and passed directly to the template. No pre-processing is done on the data, so the template needs to handle aspects like None values and fields that have values that may interfere with parsing reStructuredText.

Template Helpers

These helper functions are exposed using their short name (without the module prefix) in the template context.

sphinxcontrib.datatemplates.helpers.make_list_table(headers, data, title='', columns=None)

Build a list-table directive.

Parameters:
  • headers – List of header values.
  • data – Iterable of row data, yielding lists or tuples with rows.
  • title – Optional text to show as the table title.
  • columns – Optional widths for the columns.
sphinxcontrib.datatemplates.helpers.make_list_table_from_mappings(headers, data, title, columns=None)

Build a list-table directive.

Parameters:
  • headers – List of tuples containing header title and key value.
  • data – Iterable of row data, yielding mappings with rows.
  • title – Optional text to show as the table title.
  • columns – Optional widths for the columns.

JSON Samples

Data File

{
    "key1": "value1",
    "key2": [
        "list item 1",
        "list item 2",
        "list item 3"
    ],
    "nested-list": [
        ["a", "b", "c"],
        ["A", "B", "C"]
    ],
    "mapping-series": [
        {"cola": "a", "colb": "b", "colc": "c"},
        {"cola": "A", "colb": "B", "colc": "C"}
    ]
}

Template File

.. -*- mode: rst -*-

Static Heading
--------------

Individual Item
~~~~~~~~~~~~~~~

{{ data['key1'] }}

List of Items
~~~~~~~~~~~~~

{% for item in data['key2'] %}
- {{item}}
{% endfor %}

Nested List Table
~~~~~~~~~~~~~~~~~

Rendering a table from a list of nested sequences using hard-coded
headers.

{{ make_list_table(
    ['One', 'Two', 'Three'],
    data['nested-list'],
    title='Table from nested lists',
    ) }}

Mapping Series Table
~~~~~~~~~~~~~~~~~~~~

Rendering a table from a list of nested dictionaries using dynamic
headers.

{{ make_list_table_from_mappings(
    [('One', 'cola'), ('Two', 'colb'), ('Three', 'colc')],
    data['mapping-series'],
    title='Table from series of mappings',
    ) }}

Loading the Template

.. datatemplate:json:: sample.json
   :template: sample.tmpl

Rendered Output

Static Heading

Individual Item

value1

List of Items
  • list item 1
  • list item 2
  • list item 3
Nested List Table

Rendering a table from a list of nested sequences using hard-coded headers.

Table from nested lists
One Two Three
a b c
A B C
Mapping Series Table

Rendering a table from a list of nested dictionaries using dynamic headers.

Table from series of mappings
One Two Three
a b c
A B C

YAML Samples

Single Document

Data File

---
key1: value1
key2:
  - list item 1
  - list item 2
  - list item 3
nested-list:
  - ['a', 'b', 'c']
  - ['A', 'B', 'C']
mapping-series:
  - cola: a
    colb: b
    colc: c
  - cola: A
    colb: B
    colc: C

Template File

.. -*- mode: rst -*-

Static Heading
--------------

Individual Item
~~~~~~~~~~~~~~~

{{ data['key1'] }}

List of Items
~~~~~~~~~~~~~

{% for item in data['key2'] %}
- {{item}}
{% endfor %}

Nested List Table
~~~~~~~~~~~~~~~~~

Rendering a table from a list of nested sequences using hard-coded
headers.

{{ make_list_table(
    ['One', 'Two', 'Three'],
    data['nested-list'],
    title='Table from nested lists',
    ) }}

Mapping Series Table
~~~~~~~~~~~~~~~~~~~~

Rendering a table from a list of nested dictionaries using dynamic
headers.

{{ make_list_table_from_mappings(
    [('One', 'cola'), ('Two', 'colb'), ('Three', 'colc')],
    data['mapping-series'],
    title='Table from series of mappings',
    ) }}

Loading the Template

.. datatemplate:yaml:: sample.yaml
   :template: sample.tmpl

Rendered Output

Static Heading
Individual Item

value1

List of Items
  • list item 1
  • list item 2
  • list item 3
Nested List Table

Rendering a table from a list of nested sequences using hard-coded headers.

Table from nested lists
One Two Three
a b c
A B C
Mapping Series Table

Rendering a table from a list of nested dictionaries using dynamic headers.

Table from series of mappings
One Two Three
a b c
A B C

Multiple Documents

Data File

key1: value1

---
key: value
key1: different value


Template File

.. -*- mode: rst -*-

Static Heading
--------------

Individual Item
~~~~~~~~~~~~~~~

{{ data[0]|tojson }}

List of Items
~~~~~~~~~~~~~

{% for item in data %}
- {{item|tojson}}
  
  - {{item.key}}
  - {{item.key1}}
{% endfor %}


Mapping Series Table
~~~~~~~~~~~~~~~~~~~~

Rendering a table from a list of nested dictionaries using dynamic
headers.

{{ make_list_table_from_mappings(
    [('Key', 'key'), ('Key One', 'key1')],
    data,
    title='Table from series of mappings',
    ) }}

Loading the Template

.. datatemplate:yaml:: sample-multiple.yaml
   :template: sample-multiple.tmpl
   :multiple-documents:

Rendered Output

Static Heading
Individual Item

{“key1”: “value1”}

List of Items
  • {“key1”: “value1”}
    • value1
  • {“key”: “value”, “key1”: “different value”}
    • value
    • different value
Mapping Series Table

Rendering a table from a list of nested dictionaries using dynamic headers.

Table from series of mappings
Key Key One
None value1
value different value

XML Samples

Data File

<sample>
    <key1>value1</key1>
    <key2>
        <item>list item 1</item>
        <item>list item 2</item>
        <item special='yes'>list item 3</item>
    </key2>
    <mappingseries>
        <mapping>
            <cola special='yes'>a</cola>
            <colb>b</colb>
            <colc>c</colc>
        </mapping>
        <mapping>
            <cola>A</cola>
            <colb special='yes'>B</colb>
            <colc>C</colc>
        </mapping>
    </mappingseries>
</sample>

Template File

.. -*- mode: rst -*-

Static Heading
--------------

Individual Item
~~~~~~~~~~~~~~~

{{ data.find('key1').text }}

List of Items
~~~~~~~~~~~~~

{% for item in data.find('key2') %}
- {{item.text}}
{% endfor %}

XPath for Items
~~~~~~~~~~~~~~~

See `XPath support <https://docs.python.org/3/library/xml.etree.elementtree.html#xpath-support>`_

{% for item in data.findall(".//*[@special='yes']") %}
- {{item.text}}
{% endfor %}

Loading the Template

.. datatemplate:xml:: sample.xml
   :template: xml-sample.tmpl

Rendered Output

Static Heading

Individual Item

value1

List of Items
  • list item 1
  • list item 2
  • list item 3
XPath for Items

See XPath support

  • list item 3
  • a
  • B

Import-Module Samples

Template File

.. -*- mode: rst -*-

Static Heading
--------------

List of Directory Entries
~~~~~~~~~~~~~~~~~~~~~~~~~~

{% for item in data.scandir() %}
- {{item.name}}'s size is {{item.stat().st_size}} Bytes
{% endfor %}

File Path of the Null Device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``{{data.devnull}}``

Loading the Template

.. datatemplate:import-module:: os
   :template: import-module-sample.tmpl

Rendered Output

Static Heading

List of Directory Entries
  • dbm.rst’s size is 433 Bytes
  • sample.xml’s size is 483 Bytes
  • inline.rst’s size is 928 Bytes
  • legacy.rst’s size is 411 Bytes
  • index.rst’s size is 765 Bytes
  • using.rst’s size is 4476 Bytes
  • sampledbm.dat’s size is 519 Bytes
  • yaml.rst’s size is 954 Bytes
  • csv.rst’s size is 532 Bytes
  • conf.py’s size is 15468 Bytes
  • make_dbm.py’s size is 114 Bytes
  • sample.csv’s size is 36 Bytes
  • _templates’s size is 4096 Bytes
  • sampledbm.dir’s size is 29 Bytes
  • sample-multiple.yaml’s size is 53 Bytes
  • json.rst’s size is 410 Bytes
  • _build’s size is 4096 Bytes
  • sample.yaml’s size is 212 Bytes
  • import-module.rst’s size is 419 Bytes
  • xml.rst’s size is 416 Bytes
  • _static’s size is 4096 Bytes
  • sample.json’s size is 319 Bytes
File Path of the Null Device

/dev/null

CSV Samples

Data File

a	b	c
Eins	Zwei	Drei
1	2	3
I	II	III

Template File

.. -*- mode: rst -*-

Static Heading
--------------

Individual Cell in Row
~~~~~~~~~~~~~~~~~~~~~~

{{ data[0].a }}

List of Cells in Row
~~~~~~~~~~~~~~~~~~~~

{% for item in data[0].items() %}
- {{item[0]}}: {{item[1]}}
{% endfor %}

Mapping Series Table
~~~~~~~~~~~~~~~~~~~~

Rendering a table from a list of nested dictionaries using dynamic
headers.

{{ make_list_table_from_mappings(
    [('One', 'a'), ('Two', 'b'), ('Three', 'c')],
    data,
    title='Table from series of mappings',
    ) }}

Loading the Template

.. datatemplate:csv:: sample.csv
    :template: csv-sample.tmpl
    :headers:
    :dialect: excel-tab

Rendered Output

Static Heading

Individual Cell in Row

Eins

List of Cells in Row
  • a: Eins
  • b: Zwei
  • c: Drei
Mapping Series Table

Rendering a table from a list of nested dictionaries using dynamic headers.

Table from series of mappings
One Two Three
Eins Zwei Drei
1 2 3
I II III

DBM Samples

Creating Data File

import dbm.dumb

with dbm.dumb.open("sampledbm", "c") as db:
    db[b"Hi"] = b"Hello"
    db[b"Bye"] = b"Goodbye"

Template File

.. -*- mode: rst -*-

Static Heading
--------------

Individual Item
~~~~~~~~~~~~~~~

- With decoding {{ data['Hi'].decode('ascii') }}
- Without decoding {{ data['Hi'] }}

List of Items
~~~~~~~~~~~~~

{% for item in data.items() %}
- {{item[0]}} -> {{item[1]}}
{% endfor %}

Loading the Template

.. datatemplate:dbm:: sampledbm
   :template: dbm-sample.tmpl

Rendered Output

Static Heading

Individual Item
  • With decoding Hello
  • Without decoding b’Hello’
List of Items
  • b’Hi’ -> b’Hello’
  • b’Bye’ -> b’Goodbye’

Inline Sample (JSON)

Data File

{
    "key1": "value1",
    "key2": [
        "list item 1",
        "list item 2",
        "list item 3"
    ],
    "nested-list": [
        ["a", "b", "c"],
        ["A", "B", "C"]
    ],
    "mapping-series": [
        {"cola": "a", "colb": "b", "colc": "c"},
        {"cola": "A", "colb": "B", "colc": "C"}
    ]
}

Template File

Individual Item
~~~~~~~~~~~~~~~

{{ data['key1'] }}

List of Items
~~~~~~~~~~~~~

{% for item in data['key2'] %}
- {{item}}
{% endfor %}

Loading the Template

.. datatemplate:json::
   :source: sample.json

   Individual Item
   ~~~~~~~~~~~~~~~

   {{ data['key1'] }}

   List of Items
   ~~~~~~~~~~~~~

   {% for item in data['key2'] %}
   - {{item}}
   {% endfor %}

Rendered Output

Individual Item

value1

List of Items

  • list item 1
  • list item 2
  • list item 3

Legacy Samples

The datatemplate directive is should no longer be used. It is deprecated, and will be removed in the next release.

Data File

---
key1: value1
key2:
  - list item 1
  - list item 2
  - list item 3
nested-list:
  - ['a', 'b', 'c']
  - ['A', 'B', 'C']
mapping-series:
  - cola: a
    colb: b
    colc: c
  - cola: A
    colb: B
    colc: C

Template File

.. -*- mode: rst -*-

Static Heading
--------------

Individual Item
~~~~~~~~~~~~~~~

{{ data['key1'] }}

List of Items
~~~~~~~~~~~~~

{% for item in data['key2'] %}
- {{item}}
{% endfor %}

Nested List Table
~~~~~~~~~~~~~~~~~

Rendering a table from a list of nested sequences using hard-coded
headers.

{{ make_list_table(
    ['One', 'Two', 'Three'],
    data['nested-list'],
    title='Table from nested lists',
    ) }}

Mapping Series Table
~~~~~~~~~~~~~~~~~~~~

Rendering a table from a list of nested dictionaries using dynamic
headers.

{{ make_list_table_from_mappings(
    [('One', 'cola'), ('Two', 'colb'), ('Three', 'colc')],
    data['mapping-series'],
    title='Table from series of mappings',
    ) }}

Rendered Output

Static Heading

Individual Item

value1

List of Items
  • list item 1
  • list item 2
  • list item 3
Nested List Table

Rendering a table from a list of nested sequences using hard-coded headers.

Table from nested lists
One Two Three
a b c
A B C
Mapping Series Table

Rendering a table from a list of nested dictionaries using dynamic headers.

Table from series of mappings
One Two Three
a b c
A B C

Indices and tables