6. Document¶
Without documentation, no one will know what your project does, how it works, and how to use it. Even without a large user base, having good documentation is an advantage. Your future self will thank you for it. Documentation is not only important for users, but also for developers.
Types of Documentation¶
To provide documentation, there are generally two types of documentation:
- Inline documentation: Comments, docstrings and also type hints in your code. This helps developers and yourself to understand the code, and can be used to generate documentation automatically.
- Dedicated documentation site: A separate documentation site that provides a more detailed overview of your software and how to use it.
Inline Documentation¶
There is really no reason not to have good inline documentation with comments, docstrings and type hints. As discussed in the type section, type hints are self-documenting. Even if no one else ever uses or develops your project, good inline documentation will help keep your code readable and maintainable for your future self.
Docstrings¶
PEP 257 - Docstring Conventions defines the conventions for docstrings. Docstrings are used to document modules, classes, methods and functions. They can also be used to generate API reference documentation, which makes them very powerful. There are several styles, all of which follow the defined convention. Which one you choose is a matter of taste. But if you choose one, tools like ruff can lint your docstrings, and static site generators (see below) can generate a nice API reference without any further effort. This way, you get good inline documentation and a dedicated docs page at the same time.
numpy-style¶
numpydoc is a docstring format used by the NumPy and SciPy projects, and is very popular in the scientific Python community. It is also the default format for many tools such as Sphinx and MkDocs.
def add(a: float, b: float) -> float:
"""
Add two numbers.
Longer description of the function.
Parameters
----------
a : float
The first number.
b : float
The second number.
Returns
-------
float
The sum of the two numbers.
"""
return a + b
There are many more sections in numpydoc format. If you want to use the mentioned doctests, you can use the Examples
section:
def add(a: float, b: float) -> float:
"""
...
Examples
--------
>>> add(1, 2)
3.0
>>> add(1.5, 2.5)
4.0
"""
Check the numpydoc style guide for more information.
Google-style¶
Another popular docstring format is the Google style. It is used by the Google Python Style Guide, also used by many other projects and also supported by Sphinx and MkDocs.
def add(a: float, b: float) -> float:
"""
Add two numbers.
Longer description of the function.
Args:
a (float): The first number.
b (float): The second number.
Returns:
float: The sum of the two numbers.
Examples:
>>> add(1, 2)
3.0
>>> add(1.5, 2.5)
4.0
"""
return a + b
Sphinx-style¶
Sphinx also provides its own docstring format. It is not as popular as the other two formats and is not used by many projects. You need another extension installed, if you wanna use Sphinx with other formats, but besides that, there are no real advantages to use it.
def add(a: float, b: float) -> float:
"""
Add two numbers.
Longer description of the function.
:param a: The first number.
:type a: float
:param b: The second number.
:type b: float
:return: The sum of the two numbers.
:rtype: float
.. doctest::
>>> add(1, 2)
3.0
>>> add(1.5, 2.5)
4.0
"""
return a + b
Dedicated Documentation¶
Docstrings can be used to automatically generate an API reference. But for a complete documentation site, you need more than just the API reference. You can add a landing page, a getting started guide, tutorials, examples and more. The structure of always linking a user guide to an API reference and back is a good practice. This way a user can easily find information about the function signature, but also get an explanation of how to use it. See the pydantic documentation for a good example of this structure.
Your additional documentation will live in docs/
(or similar, but in its own directory):
python-package-demo/
├── docs/
│ ├── index.rst
│ └── ...
├── test/
│ ├── conftest.py # when using pytest
│ └── test_example.py
├── src/
│ └── python_package_demo/
│ ├── __init__.py
│ └── example.py
├── LICENSE
├── pyproject.toml
├── README.md
└── ...
Readme¶
This starts with the README.md, which is usually the first thing your users will see. The documentation landing page is usually very similar to the README.md, or you can provide a custom landing page. Although there are no hard and fast rules about how a README.md should be structured, it is a good idea to stick to the standard. Tools like makeareadme.com can help you create a good README.md with a good structure. Or check out this guide or just browse through some awesome readme's for inspiration.
Developer documentation¶
A dedicated developer page is also a good idea. It should contain information on how to contribute to the project, how to set up the development environment, how to run tests, and how to build the project. This is particularly important for open source projects.
Tools¶
To create a dedicated website for your documentation, you need a static website generator and somewhere to host it.
Static Site Generators¶
A static site generator is a tool that takes your documentation files and generates HTML files from them. There are different tools for this, and they all allow you to use different themes and plugins.
Sphinx¶
Sphinx is a static page generator based on the reStructured markup language. It also supports other formats (such as Markdown), but is designed for reStructured text. Sphinx is very powerful and flexible, and is probably the most popular tool used. As it has been around for a long time, there are a lot of plugins and themes available.
.rst
vs .md
¶
On the other hand, reStructured text is less intuitive to use and has a higher learning curve with a more challenging syntax than simple markdown. If you want to encourage community contributions to your documentation, markdown is the better choice, as it's easier to read and write. .rst` simply offers more features, but this is less of a problem with other more modern static site generators. Using Markdown also has the advantage that other viewers (such as your IDE or git hosting platform) are more likely to render it correctly.
.rst
syntax:
Title
=====
A simple example with a `link <https://www.google.com>`_.
.. warning::
This is a warning.
.. code-block:: python
def add(a: float, b: float) -> float:
"""
Add two numbers.
Longer description of the function.
:param a: The first number.
:type a: float
:param b: The second number.
:type b: float
:return: The sum of the two numbers.
:rtype: float
"""
return a + b
.md
syntax:
# Title
A simple example with a [link](https://www.google.com).
!!! warning
This is a warning.
```python
def add(a: float, b: float) -> float:
"""
Add two numbers.
Longer description of the function.
:param a: The first number.
:type a: float
:param b: The second number.
:type b: float
:return: The sum of the two numbers.
:rtype: float
"""
return a + b
MkDocs¶
mkdocs is a static site generator based on Markdown and only supports Markdown. It is very easy to use and has a lot of themes and plugins available. The documentation you are reading is built with the Material Theme MkDocs[]. It also provides plugins and most of the features missing from the standard markdown syntax. If you are not sure which one to use, mkdocs is a good choice.
GitBook¶
GitBook is another page generator based on Markdown that produces nice looking docs. The main pro and con is that it is proprietary and not open source. Which has the advantage that they also provide a hosting solution.
Hosting¶
The final step is to host your documentation somewhere so that it is accessible to the public.
readthedocs¶
The most popular tool used by many small to medium sized projects is readthedocs. It is free for open source projects and has many features. It can automatically build your documentation and host it for you. It also has many integrations with other tools such as GitHub, GitLab, Bitbucket and many more. It is very easy to set up and you do not need to provide your own CI/CD pipeline. You simply connect your account, which adds a web hook to your repository. It is so popular that the generated url of "https://readthedocs.yml
file.
GitHub Pages¶
GitHub Pages is another free hosting solution for open source projects. Since many projects are already hosted on GitHub, integration with the GitHub ecosystem is very easy. You can use it with Sphinx, MkDocs or just plain Markdown and choose a theme via GitHub Pages.
Other Resources¶
- Markdown Guide
- Documenting Python Code: A Complete Guide – Real Python
- Python docstring formats (styles) and examples | note.nkmk.me
- Writing Comments in Python (Guide) – Real Python
- Keep a Changelog
- Sphinx Documentation
- MkDocs Documentation
- Material for MkDocs
- Read the Docs Documentation
- Awesome Documentation Tools
- Python Documentation Best Practices