Home/Blog/Python Package Documentation: Sphinx, MkDocs, and Read the Docs Guide
Software Engineering

Python Package Documentation: Sphinx, MkDocs, and Read the Docs Guide

Create professional Python package documentation with Sphinx and MkDocs. Learn docstring formats, API generation, Read the Docs hosting, and documentation best practices.

By InventiveHQ Team

Good documentation is what transforms a Python package from usable to useful. It helps users get started, understand capabilities, and solve problems. This guide covers modern documentation tools and practices for Python packages.

Documentation Types

Professional documentation includes multiple types:

┌─────────────────────────────────────────────────────────────┐
│                   Documentation Quadrant                     │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  LEARNING                         INFORMATION                │
│  ──────────────────────────────────────────────             │
│                                                              │
│  Tutorials                        Reference                  │
│  • Get started quickly            • API documentation        │
│  • Learning-oriented              • Function signatures      │
│  • Step-by-step                   • Complete & accurate      │
│                                                              │
│  ──────────────────────────────────────────────             │
│                                                              │
│  How-to Guides                    Explanation                │
│  • Solve specific problems        • Background & context     │
│  • Task-oriented                  • Why things work          │
│  • Practical steps                • Architecture decisions   │
│                                                              │
│  DOING                            UNDERSTANDING              │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Docstring Formats

Clean and readable, works well with type hints:

def process_data(input_path: str, output_path: str, *, validate: bool = True) -> dict:
    """Process data from input file and write to output.

    Reads the input file, applies transformations, and writes
    the result to the output path.

    Args:
        input_path: Path to the input file. Must exist.
        output_path: Path for the output file. Created if doesn't exist.
        validate: Whether to validate data before processing.
            Defaults to True.

    Returns:
        A dictionary containing processing statistics:
            - processed: Number of records processed
            - errors: Number of errors encountered
            - duration: Processing time in seconds

    Raises:
        FileNotFoundError: If input_path doesn't exist.
        ValidationError: If validate=True and data is invalid.

    Example:
        >>> stats = process_data("input.csv", "output.json")
        >>> print(stats["processed"])
        100
    """

NumPy Style

Common in scientific Python:

def calculate_statistics(data, axis=None):
    """
    Calculate basic statistics for the input data.

    Parameters
    ----------
    data : array_like
        Input data for statistical calculation.
    axis : int or None, optional
        Axis along which to compute statistics.
        If None, compute over flattened array.

    Returns
    -------
    dict
        Dictionary containing:
        - mean : float
            Arithmetic mean of the data.
        - std : float
            Standard deviation.
        - min : float
            Minimum value.
        - max : float
            Maximum value.

    See Also
    --------
    numpy.mean : Compute arithmetic mean.
    numpy.std : Compute standard deviation.

    Examples
    --------
    >>> data = [1, 2, 3, 4, 5]
    >>> stats = calculate_statistics(data)
    >>> stats['mean']
    3.0
    """

Sphinx (reStructuredText) Style

Native Sphinx format:

def fetch_user(user_id, include_details=False):
    """
    Fetch a user by ID.

    :param user_id: The unique user identifier.
    :type user_id: int
    :param include_details: Include additional user details.
    :type include_details: bool, optional
    :returns: User object or None if not found.
    :rtype: User or None
    :raises ValueError: If user_id is negative.

    .. note::
       This function makes a network request.

    .. warning::
       Rate limited to 100 requests per minute.
    """

Sphinx is the standard for Python documentation.

Setup

pip install sphinx sphinx-rtd-theme sphinx-autodoc-typehints

# Initialize in your project
cd my-package
sphinx-quickstart docs

# Answer prompts:
# > Separate source and build directories? [n]: n
# > Project name: My Package
# > Author name(s): Your Name
# > Project release: 1.0.0

Project Structure

my-package/
├── src/
│   └── my_package/
│       ├── __init__.py
│       └── core.py
├── docs/
│   ├── conf.py           # Sphinx configuration
│   ├── index.rst         # Main page
│   ├── installation.rst
│   ├── quickstart.rst
│   ├── api.rst           # API reference
│   └── _static/          # Custom CSS, images
├── pyproject.toml
└── README.md

Configuration (conf.py)

# docs/conf.py
import os
import sys

# Add source to path for autodoc
sys.path.insert(0, os.path.abspath("../src"))

# Project information
project = "My Package"
copyright = "2026, Your Name"
author = "Your Name"
release = "1.0.0"

# Extensions
extensions = [
    "sphinx.ext.autodoc",        # Auto-generate from docstrings
    "sphinx.ext.napoleon",       # Google/NumPy docstring support
    "sphinx.ext.viewcode",       # Add links to source code
    "sphinx.ext.intersphinx",    # Link to other projects
    "sphinx_autodoc_typehints",  # Type hints in docs
]

# Napoleon settings (for Google/NumPy docstrings)
napoleon_google_docstring = True
napoleon_numpy_docstring = True
napoleon_include_init_with_doc = True

# Autodoc settings
autodoc_default_options = {
    "members": True,
    "undoc-members": True,
    "show-inheritance": True,
}
autodoc_typehints = "description"

# Intersphinx mapping
intersphinx_mapping = {
    "python": ("https://docs.python.org/3", None),
    "requests": ("https://requests.readthedocs.io/en/latest/", None),
}

# Theme
html_theme = "sphinx_rtd_theme"
html_theme_options = {
    "navigation_depth": 4,
}

Main Page (index.rst)

My Package
==========

My Package is a Python library for doing awesome things.

.. toctree::
   :maxdepth: 2
   :caption: Contents:

   installation
   quickstart
   api
   changelog

Features
--------

* Feature one
* Feature two
* Feature three

Quick Example
-------------

.. code-block:: python

   from my_package import process

   result = process("input.txt")
   print(result)

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

API Reference (api.rst)

API Reference
=============

Core Module
-----------

.. automodule:: my_package.core
   :members:
   :undoc-members:
   :show-inheritance:

Utilities
---------

.. automodule:: my_package.utils
   :members:

Specific Function
-----------------

.. autofunction:: my_package.process_data

Building Documentation

# Build HTML
cd docs
make html

# View locally
open _build/html/index.html

# Clean build
make clean html

MkDocs: Simple Markdown Docs

MkDocs uses Markdown and is simpler to configure.

Setup

pip install mkdocs mkdocs-material mkdocstrings[python]

# Initialize
mkdocs new .

Project Structure

my-package/
├── src/
│   └── my_package/
├── docs/
│   ├── index.md
│   ├── installation.md
│   ├── quickstart.md
│   ├── api/
│   │   └── core.md
│   └── assets/
├── mkdocs.yml
└── pyproject.toml

Configuration (mkdocs.yml)

# mkdocs.yml
site_name: My Package
site_url: https://mypackage.readthedocs.io/
repo_url: https://github.com/user/my-package
repo_name: user/my-package

theme:
  name: material
  features:
    - navigation.tabs
    - navigation.sections
    - content.code.copy
  palette:
    - scheme: default
      primary: indigo
      accent: indigo

plugins:
  - search
  - mkdocstrings:
      default_handler: python
      handlers:
        python:
          options:
            show_source: true
            show_root_heading: true

nav:
  - Home: index.md
  - Getting Started:
    - Installation: installation.md
    - Quick Start: quickstart.md
  - API Reference:
    - Core: api/core.md
  - Changelog: changelog.md

markdown_extensions:
  - pymdownx.highlight:
      anchor_linenums: true
  - pymdownx.superfences
  - admonition
  - toc:
      permalink: true

API Documentation (api/core.md)

# Core Module

Main functionality of the package.

## process_data

::: my_package.core.process_data

## DataProcessor

::: my_package.core.DataProcessor
    options:
      members: true
      show_source: false

Building

# Serve locally with hot reload
mkdocs serve

# Build static site
mkdocs build

# Deploy to GitHub Pages
mkdocs gh-deploy

Read the Docs

Host your documentation for free with automatic builds.

Configuration (.readthedocs.yaml)

# .readthedocs.yaml
version: 2

build:
  os: ubuntu-22.04
  tools:
    python: "3.11"

# Sphinx
sphinx:
  configuration: docs/conf.py

# Or MkDocs
# mkdocs:
#   configuration: mkdocs.yml

python:
  install:
    - method: pip
      path: .
      extra_requirements:
        - docs

pyproject.toml Docs Dependencies

[project.optional-dependencies]
docs = [
    "sphinx>=7.0",
    "sphinx-rtd-theme>=1.0",
    "sphinx-autodoc-typehints>=1.0",
    # Or for MkDocs:
    # "mkdocs>=1.5",
    # "mkdocs-material>=9.0",
    # "mkdocstrings[python]>=0.24",
]

Setting Up Read the Docs

  1. Push your code to GitHub/GitLab/Bitbucket
  2. Sign up at readthedocs.org
  3. Import your project
  4. Configure build settings
  5. Docs build automatically on each push

Versioned Documentation

Read the Docs builds docs for:

  • Main branch (latest)
  • Tags (stable versions)
  • Feature branches (preview)
# .readthedocs.yaml
version: 2

build:
  os: ubuntu-22.04
  tools:
    python: "3.11"

# Build PDF/EPUB
formats:
  - pdf
  - epub

Documentation Best Practices

1. Write README First

# My Package

[![PyPI](https://img.shields.io/pypi/v/my-package)](https://pypi.org/project/my-package/)
[![Docs](https://readthedocs.org/projects/my-package/badge/)](https://my-package.readthedocs.io/)

Short description of what your package does.

## Installation

```bash
pip install my-package

Quick Start

from my_package import process

result = process("input.txt")

Documentation

Full documentation: https://my-package.readthedocs.io/

License

MIT


### 2. Include Working Examples

```python
def calculate_sum(numbers: list[int]) -> int:
    """Calculate the sum of numbers.

    Example:
        >>> calculate_sum([1, 2, 3])
        6
        >>> calculate_sum([])
        0
        >>> calculate_sum([-1, 1])
        0

    Note:
        Examples are tested with doctest.
    """
    return sum(numbers)

3. Document the Why, Not Just What

def connect(host: str, port: int, timeout: float = 30.0) -> Connection:
    """Connect to the server.

    The timeout defaults to 30 seconds, which works well for most
    network conditions. For slow connections or when connecting to
    remote servers, you may need to increase this value.

    If the server uses a non-standard port, ensure your firewall
    allows outbound connections on that port.

    Args:
        host: Server hostname or IP address.
        port: Server port number.
        timeout: Connection timeout in seconds. Increase for slow
            networks or distant servers.

    Returns:
        Active connection to the server.
    """

4. Use Admonitions

!!! note
    This feature requires Python 3.10+

!!! warning
    This operation cannot be undone.

!!! tip
    Use `--verbose` for detailed output.

!!! danger
    Never commit API keys to version control.
.. note::
   This feature requires Python 3.10+

.. warning::
   This operation cannot be undone.

5. Keep Docs in Sync

# pyproject.toml
[tool.pytest.ini_options]
addopts = "--doctest-modules"

# Run doctests to verify examples
# pytest src/ --doctest-modules

Project Documentation Structure

docs/
├── index.rst/md           # Introduction, quick links
├── installation.rst/md    # How to install
├── quickstart.rst/md      # 5-minute tutorial
├── tutorials/             # In-depth tutorials
│   ├── tutorial1.rst/md
│   └── tutorial2.rst/md
├── how-to/                # Task-oriented guides
│   ├── configure.rst/md
│   └── deploy.rst/md
├── api/                   # API reference
│   ├── core.rst/md
│   └── utils.rst/md
├── changelog.rst/md       # Version history
└── contributing.rst/md    # How to contribute

Adding Badges

# Badges for README

[![PyPI version](https://badge.fury.io/py/my-package.svg)](https://pypi.org/project/my-package/)
[![Python versions](https://img.shields.io/pypi/pyversions/my-package.svg)](https://pypi.org/project/my-package/)
[![Documentation](https://readthedocs.org/projects/my-package/badge/)](https://my-package.readthedocs.io/)
[![Tests](https://github.com/user/my-package/actions/workflows/test.yml/badge.svg)](https://github.com/user/my-package/actions)
[![Coverage](https://codecov.io/gh/user/my-package/branch/main/graph/badge.svg)](https://codecov.io/gh/user/my-package)
[![License](https://img.shields.io/pypi/l/my-package.svg)](https://github.com/user/my-package/blob/main/LICENSE)

Command Reference

Sphinx

sphinx-quickstart docs      # Initialize Sphinx
make html                   # Build HTML
make clean                  # Clean build
sphinx-build -b html . _build  # Build command

MkDocs

mkdocs new .               # Initialize MkDocs
mkdocs serve               # Local development server
mkdocs build               # Build static site
mkdocs gh-deploy           # Deploy to GitHub Pages

Next Steps

For more Python development guides, explore our complete Python packaging series.

Frequently Asked Questions

Find answers to common questions

Use Sphinx if you need autodoc from docstrings, have complex API documentation, or want reStructuredText. Use MkDocs if you prefer Markdown, want simpler setup, or are building more prose-heavy documentation. Both work well with Read the Docs.

Need Expert IT & Security Guidance?

Our team is ready to help protect and optimize your business technology infrastructure.