WARNING: This is the documentation for the LEGACY Python handler.
To read the documentation for the NEW handler,
go to the new handler documentation.
The tool used by the legacy Python handler to collect documentation from Python source code
is pytkdocs
.
It stands for (Python) Take Docs, and is supposed to be a pun on MkDocs (Make Docs?).
Like every handler, the legacy Python handler accepts both global and local options.
Some options are global only, and go directly under the handler's name.
-
import
: this option is used to import Sphinx-compatible objects inventories from other documentation sites. For example, you can import the standard library objects inventory like this:plugins: - mkdocstrings: handlers: python: import: - https://docs.python-requests.org/en/master/objects.inv
When importing an inventory, you enable automatic cross-references to other documentation sites like the standard library docs or any third-party package docs. Typically, you want to import the inventories of your project's dependencies, at least those that are used in the public API.
NOTE: This global option is common to all handlers, however they might implement it differently (or not even implement it).
-
paths
: this option is used to provide filesystem paths in which to search for Python modules. Non-absolute paths are computed as relative to MkDocs configuration file. Example:plugins: - mkdocstrings: handlers: python: paths: [src] # search packages in the src folder
More details at Finding modules.
-
setup_commands
: this option is used to instructpytkdocs
, the tool responsible for collecting data from sources, to run Python statements before starting to collect data. It is declared as a list of strings:plugins: - mkdocstrings: handlers: python: setup_commands: - import os - import django - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_django_app.settings") - django.setup()
The setup commands are executed only once, when the
pytkdocs
background process is started.
-
The other options can be used both globally and locally, under the options
key.
For example, globally:
plugins:
- mkdocstrings:
handlers:
python:
options:
do_something: true
...and locally, overriding the global configuration:
::: package.module.class
options:
do_something: false
These options affect how the documentation is collected from sources and renderered: headings, members, docstrings, etc.
options:
show_root_heading: false
show_root_toc_entry: false
Right now, pytkdocs
supports the Google-style, Numpy-style and reStructuredText-style docstring formats.
The style used by default is the Google-style.
You can configure what style you want to use with
the docstring_style
and docstring_options
options,
both globally or per autodoc instruction.
You can see examples of Google-style docstrings in Napoleon's documentation.
Docstrings sections are parsed by pytkdocs
and rendered by mkdocstrings.
Supported sections are:
Arguments
(orArgs
,Parameters
,Params
)Attributes
Examples
(orExample
)Raises
(orRaise
,Except
,Exceptions
)Returns
(orReturn
)
Additionally, any section that is not recognized will be transformed into its admonition equivalent. For example:
=== "Original"
```python
"""
Note: You can disable this behavior with the replace_admonitions
option.
To prevent `pytkdocs` from converting sections to admonitions,
use the `replace_admonitions`:
```md
::: my_package.my_module
options:
docstring_style: google # this is the default
docstring_options:
replace_admonitions: no
```
So meta!
"""
```
=== "Modified"
```python
"""
!!! note "You can disable this behavior with the replace_admonitions
option."
To prevent `pytkdocs` from converting sections to admonitions,
use the `replace_admonitions`:
```md
::: my_package.my_module
options:
docstring_style: google # this is the default
docstring_options:
replace_admonitions: no
```
So meta!
"""
```
=== "Result"
> NOTE: You can disable this behavior with the replace_admonitions
parser option.
> To prevent pytkdocs
from converting sections to admonitions,
> use the replace_admonitions
parser option:
>
> md > ::: my_package.my_module > options: > docstring_style: google # this is the default > docstring_options: > replace_admonitions: no >
>
> So meta!
As shown in the above example, this can be disabled
with the replace_admonitions
option of the Google-style parser:
::: my_package.my_module
options:
docstring_style: google # this is the default
docstring_options:
replace_admonitions: no
Type annotations are read both in the code and in the docstrings.
EXAMPLE: Example with a function
Expand the source at the end to see the original code!options: show_root_heading: false show_root_toc_entry: false
IMPORTANT: Extra dependency required
You'll need an extra dependency to parse Numpy-style docstrings:
pdm add -d --group docs 'pytkdocs[numpy-style]'
poetry add -D 'pytkdocs[numpy-style]'
pip install 'pytkdocs[numpy-style]'
# etc.
NOTE: As Numpy-style is partially supported by the underlying parser,
you may experience problems in the building process if your docstring
has a Methods
section in the class docstring
(see #366).
You can see examples of Numpy-style docstrings in numpydoc's documentation.
WARNING: Partial support
Only RST-style is supported, not the whole RST markup specification.
You can see examples of reStructuredText-style docstrings in Sphinx's documentation.
Docstrings directives are parsed by pytkdocs
and rendered by mkdocstrings.
Supported directives are:
param
(orparameter
,arg
,argument
,key
,keyword
)type
raises
(orraise
,except
,exception
)var
(orivar
,cvar
)vartype
returns
(orreturn1
)rtype
Details about how to use each directive can be found in the Sphinx domain documentation
Type annotations are read both in the code and in the docstrings.
EXAMPLE: Example with a function
Expand the source at the end to see the original code!::: snippets.function_annotations_rst:my_function options: docstring_style: restructured-text show_root_heading: no show_root_toc_entry: no
There are multiple ways to tell the handler where to find your packages/modules.
The recommended method is to use the paths
option, as it's the only one
that works with the -f
option of MkDocs, allowing to build the documentation
from any location on the file system. Indeed, the paths provided with the
paths
option are computed as relative to the configuration file (mkdocs.yml),
so that the current working directory has no impact on the build process:
you can build the docs from any location on your filesystem.
TIP: This is the recommended method.
-
mkdocs.yml in root, package in root
root/ mkdocs.yml package/
plugins: - mkdocstrings: handlers: python: paths: [.] # actually not needed, default
-
mkdocs.yml in root, package in subfolder
root/ mkdocs.yml src/ package/
plugins: - mkdocstrings: handlers: python: paths: [src]
-
mkdocs.yml in subfolder, package in root
root/ docs/ mkdocs.yml package/
plugins: - mkdocstrings: handlers: python: paths: [..]
-
mkdocs.yml in subfolder, package in subfolder
root/ docs/ mkdocs.yml src/ package/
plugins: - mkdocstrings: handlers: python: paths: [../src]
Except for case 1, which is supported by default, we strongly recommend
to set the path to your packages using this option, even if it works without it
(for example because your project manager automatically adds src
to PYTHONPATH),
to make sure anyone can build your docs from any location on their filesystem.
Behind the scenes, the handler will actually insert the specified paths in front of sys.path
.
WARNING: This method has limitations.
This method might work for you, with your current setup,
but not for others trying your build your docs with their own setup/environment.
We recommend to use the paths
method instead.
You can take advantage of the usual Python loading mechanisms.
In Bash and other shells, you can run your command like this
(note the prepended PYTHONPATH=...
):
-
mkdocs.yml in root, package in root
root/ mkdocs.yml package/
PYTHONPATH=. mkdocs build # actually not needed, default
-
mkdocs.yml in root, package in subfolder
root/ mkdocs.yml src/ package/
PYTHONPATH=src mkdocs build
-
mkdocs.yml in subfolder, package in root
root/ docs/ mkdocs.yml package/
PYTHONPATH=. mkdocs build -f docs/mkdocs.yml
-
mkdocs.yml in subfolder, package in subfolder
root/ docs/ mkdocs.yml src/ package/
PYTHONPATH=src mkdocs build -f docs/mkdocs.yml
WARNING: This method has limitations.
This method might work for you, with your current setup,
but not for others trying your build your docs with their own setup/environment.
We recommend to use the paths
method instead.
Install your package in the current environment, and run MkDocs:
=== "pip"
bash . venv/bin/activate pip install -e . mkdocs build
=== "PDM"
bash pdm install pdm run mkdocs build
=== "Poetry"
bash poetry install poetry run mkdocs build
WARNING: This method has limitations.
This method might work for you, with your current setup,
but not for others trying your build your docs with their own setup/environment.
We recommend to use the paths
method instead.
You can use the setup commands to modify sys.path
:
plugins:
- mkdocstrings:
handlers:
python:
setup_commands:
- import sys
- sys.path.append("src")
# or sys.path.insert(0, "src")
You may want to generate documentation for a package while its dependencies are not available.
The Python handler provides itself no builtin way to mock libraries,
but you can use the setup_commands
to mock them manually:
plugins:
- mkdocstrings:
handlers:
python:
setup_commands:
- import sys
- from unittest.mock import MagicMock as mock
- sys.modules["lib1"] = mock()
- sys.modules["lib2"] = mock()
- sys.modules["lib2.module1"] = mock()
- sys.modules["lib2.module1.moduleB"] = mock()
# etc
Here are some CSS rules for the Material for MkDocs theme:
/* Indentation. */
div.doc-contents:not(.first) {
padding-left: 25px;
border-left: .05rem solid var(--md-typeset-table-color);
}
Here are some CSS rules for the built-in ReadTheDocs theme:
/* Indentation. */
div.doc-contents:not(.first) {
padding-left: 25px;
border-left: 4px solid rgba(230, 230, 230);
}