Skip to content

Instantly share code, notes, and snippets.

@thevickypedia
Last active December 4, 2021 17:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thevickypedia/94408038a82eec773c1f79eed230ccc2 to your computer and use it in GitHub Desktop.
Save thevickypedia/94408038a82eec773c1f79eed230ccc2 to your computer and use it in GitHub Desktop.
Configure sphinx docs when using Pydantic

Sphinx Auto-docs and Pydantic Configuration

Sphinx autogen docs and pydantic don't get along.

Problem:

  • Using the BaseModel from pydantic takes the class members as arguments.
    • These arguments are displayed (along with the values) in the docs whether the user wants it or not.
import os

from pydantic import BaseModel


class Demo(BaseModel):
    """This is a demo class with a class member.

    >>> Demo

    """

    VARIABLE: str = os.environ.get('phrase', 'December2021')
The above code block will be displayed as the following in the docs.

class module.Demo(*, VARIABLE: str = December2021)

  • Operations specified for class members will be executed when docs are generated.
    • For instance, if VARIABLE: str = input('Enter your name:') is mentioned as a class member, the doc generation process will be on hold until an input is entered.

Acceptance:

  • .. automodule:: will run the doc generation on the whole file and not just the class.
  • Running docs generation will execute the class members including any operations specified.
  • There is no straight forward way to block or hide the class members from the docs.
    • This is because, pydantic takes class members as arguments and this particularly executes when docs are generated.
    • So, :exclude-members: or # : :meta hide-value will not work because when it makes to sphinx they are not members, but arguments.

Solution:

Hacky but simple:
  • Export/set an env var before initiating the doc generation and make a condition based on which the class members are declared.
    • This way, the class members are never set and the operations are never executed during doc generation.
Proper but lengthy:
  • Use .. autoclass:: in place of .. automodule:: in the index.rst

    • This way, the user can specify/use customized signature by specifying the arguments that have to be in the docs.
    • This will override the parameter list of the function and hide the unwanted arguments in the docs.
    • This will still display the class members in the docs, hiding their values.
  • The downside of using .. autoclass:: is, the docs are generated only for that particular class.

    • Each class requires its own section of toctree in the index.rst file
import os
from base64 import urlsafe_b64encode
from uuid import uuid1

from pydantic import BaseModel


class DemoFunction(BaseModel):
    """Demo function.

    >>> DemoFunction

    """

    SECRET: bytes = urlsafe_b64encode(uuid1().bytes).rstrip(b'=').decode('ascii')
    FilePath: str = os.getcwd()
Sample rst section to include NO arguments:
.. autoclass:: DemoFunction()
   :members:
   :undoc-members:
   :exclude-members: SECRET, FilePath

📓 The empty open and close () at the end of the class name is to denote that, the docs should not include any args.

📓 The :exclude-members: is to denote that the class members should not be included in the docs.

Sample rst section to include specific arguments:
.. autoclass:: DemoFunction(FilePath)
   :members:
   :undoc-members:
..
   :exclude-members: SECRET, FilePath

📓 Only the arg names which have to be displayed in the docs should go within the parentheses. In this case the arg file_path will be included but secret.

📓 The .. before :exclude-members: is a way to comment the following section in reStructured Text format.
In this case, since the :exclude-members: section is commented, the class members will be displayed (WITHOUT their values) in the docs.
Also note that, the class members will be displayed only when type hinting is done in the class. Bare variable declaration will not make it to the docs.

To actually include pydantic args in sphinx and control the format of the docstring section: autodoc-pydantic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment