How can one create a Sphinx directive that creates documentation from an externally defined data structure?

27 views
Skip to first unread message

Rollo Konig-Brock

unread,
Jun 29, 2020, 3:59:44 PM6/29/20
to sphinx-users
Hey there,

I posted this question on stack overflow, but I think it's a bit too niche for that site and it's better to just ask the hardcore Sphinx users.

------

How can one create a Sphinx directive that creates documentation from an externally defined data structure?

For context, I have some classes that automatically create attributes based on a JSON response.

class Model:
    def __init__(self, json_data):
        self.__dict__ = json_data


model = Model({"a": 1})
model.a

The issue I'm having is documenting this in Sphinx. I could possibly do it manually like so:

.. autoclass:: Model

    .. attribute:: a

However the properties are numerous, outside my control, which presents issues keeping the documentation up to date with the backend.

Attempting to remedy this problem I've built up a data-structure pulled from a swagger document that contains information about these dynamic properties. However I have no idea how to apply this in Sphinx. I've looked into custom directives and domains, but without some serious digging into the internals I don't understand how to create a directive that creates other directives.

In essence I would like to do the following.

.. autoclass:: Model

    .. custom_set_of_attributes_directive:: model_schema

Which would be equivalent to:

.. autoclass:: Model

    .. attribute:: a
    .. attribute:: b
    .. attribute:: c

Komiya Takeshi

unread,
Jul 7, 2020, 10:14:54 AM7/7/20
to sphinx...@googlegroups.com
Hi,

AFAIK, there are no way to expand the contents for directives via own
custom directive. As a similar way, you can generate whole of
directive via own custom directive:

.. custom_set_of_attributes_directive:: Model x model_schema

Which would be equivalent to:

.. autoclass:: Model

.. attribute:: a
.. attribute:: b
.. attribute:: c

The nested_parse() will help you to implement such a feature. It
allows you to pass content to the parser.

```
from docutils.statemachine import StringList

class CustomSetOfAttributeDirective(Directive):
def run(self):
# generate content
content = StringList()
content.append(".. autoclass:: Model")
content.append("")
content.append(" .. attribute:: a")
content.append(" .. attribute:: b")
content.append(" .. attribute:: c")

# call nested_parse to parse content using reST parser
node = nodes.Element()
self.state.nested_parse(content, self.content_offset, node) #
the result will be stored into `node`.

return node.children
```

I hope this helps you :-)

Thanks,
Takeshi KOMIYA

2020年6月30日(火) 4:59 Rollo Konig-Brock <rol...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups "sphinx-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sphinx-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sphinx-users/58214896-735d-4b47-94d1-9ab2f907e6aeo%40googlegroups.com.

Rollo Konig-Brock

unread,
Jul 8, 2020, 9:12:45 AM7/8/20
to sphinx-users
Thanks Komiya, that's awesome. 
> To unsubscribe from this group and stop receiving emails from it, send an email to sphinx...@googlegroups.com.

Doug Hellmann

unread,
Jul 8, 2020, 9:18:00 AM7/8/20
to sphinx...@googlegroups.com
If you have the swagger data in a machine-parseable format like XML you may find sphinxcontrib-datatemplates useful for formatting it within a sphinx document. https://github.com/sphinx-contrib/datatemplates/

> Which would be equivalent to:
>
> .. autoclass:: Model
>
>
>
> .. attribute::
> a
>
> .. attribute::
> b
>
> .. attribute:: c
>
>
> --
> You received this message because you are subscribed to the Google Groups "sphinx-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sphinx-users...@googlegroups.com.

Daniel Scott

unread,
Nov 25, 2020, 10:38:09 PM11/25/20
to sphinx...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages