mkdocstrings-python
mkdocstrings-python is a handler for the mkdocstrings library, specifically designed to parse and render Python API documentation within MkDocs-generated sites. It leverages the Griffe library for static analysis of Python code to extract docstrings and signatures. The current version is 2.0.3, and it maintains an active release cadence with frequent updates and bug fixes.
Warnings
- breaking Version 2.0.0 removed previously deprecated code. Users upgrading from 1.x versions should review release notes for any functionality that might have been removed or changed.
- breaking As of version 2.0.3, mkdocstrings-python depends on 'griffelib' instead of 'griffe'. While 'griffelib' is essentially 'griffe v2', this change indicates a significant internal refactor of the underlying parsing library. Custom plugins or integrations relying directly on 'griffe' internals might be affected.
- gotcha mkdocstrings-python is an extension. You must install `mkdocs` and `mkdocstrings` separately for it to function, in addition to `mkdocstrings-python` itself.
- gotcha mkdocstrings-python needs to be explicitly enabled and configured as a handler in your `mkdocs.yml` file under the `plugins` section for it to process Python documentation directives.
- gotcha The documentation engine needs to locate your Python source code. Misconfiguration of the Python `paths` option (or `PYTHONPATH`) is a common cause of 'module not found' errors.
Install
-
pip install mkdocs mkdocstrings mkdocstrings-python
Quickstart
import os
import subprocess
import textwrap
def setup_mkdocs_project():
project_dir = "my_docs_project"
docs_dir = os.path.join(project_dir, "docs")
src_dir = os.path.join(project_dir, "my_package")
os.makedirs(docs_dir, exist_ok=True)
os.makedirs(src_dir, exist_ok=True)
# Create a dummy Python module to document
with open(os.path.join(src_dir, "__init__.py"), "w") as f:
f.write(textwrap.dedent("""
"""A simple example package."""
def greet(name: str) -> str:
"""Greets a person by name.
Args:
name: The name of the person.
Returns:
A greeting string.
"""
return f"Hello, {name}!"
class MyClass:
"""A simple example class."""
def __init__(self, value: int):
self.value = value
def get_value(self) -> int:
"""Returns the stored value."""
return self.value
"""))
# Create mkdocs.yml
mkdocs_config = textwrap.dedent(f"""
site_name: My Docs
nav:
- Home: index.md
plugins:
- search
- mkdocstrings:
handlers:
python:
paths:
- {src_dir}
""")
with open(os.path.join(project_dir, "mkdocs.yml"), "w") as f:
f.write(mkdocs_config)
# Create index.md with mkdocstrings directive
index_md_content = textwrap.dedent("""
# My Awesome Project
This is the documentation for my project.
## API Reference
::: my_package
options:
show_root_heading: false
show_root_full_path: false
show_object_full_path: false
""")
with open(os.path.join(docs_dir, "index.md" ), "w") as f:
f.write(index_md_content)
print(f"MkDocs project '{project_dir}' created. Run 'cd {project_dir} && mkdocs build' to generate docs.")
# Optionally, run mkdocs build here for a fully self-contained example
# try:
# subprocess.run(["mkdocs", "build"], cwd=project_dir, check=True)
# print(f"Docs built successfully in '{os.path.join(project_dir, 'site')}'")
# except subprocess.CalledProcessError as e:
# print(f"Error building docs: {e}")
if __name__ == "__main__":
setup_mkdocs_project()