Just like you need a map when exploring a new area, other users need guidance on your project. Undoubtedly, self-describing source code is a good practice but the code itself doesn’t explain everything.
Questions may arise such as: why the module is being written? Why is it implemented in such a way? What’s the database schema? And a common one: how on earth should I set up this project?
And now comes into play probably one of the most disliked activities by programmers …
writing a documentation.
The more complex the project is, the more documentation it needs.
However, let’s assume that you need to document your small to medium size Python project and would like to do it at the lowest cost, preferably automatically.
Systematic approach is a key
Documenting code shouldn’t take place at the end of the project. It should be done systematically and as soon as a new code snippet is added. Some recommendations are mentioned below.
Typing
Although Python is dynamically typed, type hinting has been introduced in Python 3.5.
Type hinting offers a way to statically indicate the data types expected by functions and variables.
def salary_day_checker(day: int, month: str, year: int = 2024) -> bool:
print(f"Today is {day} {month} {year}")
if day == 10:
return True
return False
salary_day_checker(20, "march")
# Today is 20 march 2024
# False
Docstrings
Use docstrings to describe the functionality of a function, class, or module. Python docstrings can be written in several formats, e.g. Google Docstring or NumPy Docstring.
def salary_day_checker(day: int, month: str, year: int = 2024) -> bool:
"""Print date and check if provided day is a salary day.
Parameters
----------
day: int
Day of month.
month: str
Month name.
year: int
Year, by default 2024.
Returns
-------
bool
True if provided day is a salary day, False otherwise.
"""
print(f"Today is {day} {month} {year}")
if day == 10:
return True
return False
README
The README file serves as a guide to a software project. It explains the project’s purpose, goes through the requirements and setup, and shows how it can be used.
README file should give a new user a good understanding and introduction to your project.
Ready-to-use Python project
For the purpose of this tutorial, a basic calculator was implemented in Python. The aim is to generate documentation for this super simple project.
Building Documentation
We’ll need 3 Python packages to build our documentation:
- MkDocs for building static pages from Markdown
- mkdocstrings for auto-generating documentation from code docstrings
- Material for MkDocs for styling the documentation
Install them as follows:
pip install mkdocs mkdocstrings[crystal,python] mkdocs-material
Simple start with MkDocs
MkDocs is a static site generator for building project documentation.
There are three main components:
- your project code
- Markdown documentation pages inside a
docs/
directory - configuration YAML file
mkdocs.yml
Create MkDocs project structure
Create a default project structure for your MkDocs project in the current directory (the directory of your Python project).
mkdocs new .
Now the Python project structure is as follows:
.
├── src # Python project
│ ├── calculator.py
│ └── run.py
├── docs # collection of documentation source files
│ └── index.md # documentation page
├── mkdocs.yml # configuration file
├── README.md
└── requirements.txt
Preview documentation
Start a built-in dev server by using the command below in your project directory. Make sure you’re in the same directory as the mkdocs.yml
configuration file.
mkdocs serve
As an output, you’ll get a URL to your served documentation. By default, http://127.0.0.1:8000.
The dev-server supports auto-reloading, so you can preview your changes as you write your documentation.
Autogenerate documentation
As it was mentioned before, MkDocs is a static site generator. In order to autogenerate documentation based on your code and docstrings use mkdocstrings
.
Configuration file
Change the configuration file mkdocs.yml
to alter how the documentation is displayed by changing the theme, e.g. use material
theme.
Specify theme docstring style in mkdocs.yml
configuration file as follows:
site_name: CALCulator Documentation
theme:
name: material
plugins:
- mkdocstrings:
default_handler: python
handlers:
python:
options:
docstring_style: numpy
features:
- search.suggest
- search.highlight
It’s time to create markdown files in docs
directory and add some references to your code.
For instance, create operations.md
file and automatically build documentation for Calculator
class:
# Arithmetic operations
::: src.calculator.Calculator
Create more pages (markdown files) and organize them in nav
section in mkdocs.yml
:
site_name: CALCulator Documentation
theme:
name: material
plugins:
- mkdocstrings:
default_handler: python
handlers:
python:
options:
docstring_style: numpy
features:
- search.suggest
- search.highlight
nav:
- Home: index.md
- User Guide:
- Functionality: operations.md
- Usage: usage.md
- Authors: authors.md
Go to http://127.0.0.1:8000/operations/ and take a look at docstrings-based documentation.
Additional configuration
By adding search
plugin to the config file, you can easily search the documentation.
Moreover, you can hide source code if your project isn’t open source.
For more configuration options go to mkdocstrings.github.io/usage or mkdocs.org/user-guide/configuration.
site_name: CALCulator Documentation
theme:
name: material
plugins:
- mkdocstrings:
default_handler: python
handlers:
python:
options:
show_source: false
docstring_style: numpy
features:
- search.suggest
- search.highlight
- search:
enabled: true
nav:
- Home: index.md
- User Guide:
- Functionality: operations.md
- Usage: usage.md
- Authors: authors.md
Deployment
If you host your Python project code on GitHub, you can easily deploy the documentation using Github Pages. GitHub repositories automatically serve static content when committed to a branch named gh-pages
.
All you have to do is run the following command:
mkdocs gh-deploy
Behind the scenes, MkDocs will build your docs and commit them to the gh-pages
branch and then push the gh-pages
branch to GitHub.
Once the process is completed, you’ll get the link to your documentation.
This tutorial project’s documentation is available here:
If you use a hosting provider different than GitHub, you have to build the documentation first. Use the following command:
mkdocs build
This will create a new directory, named site
with all documentation components. Generally, you will need to copy the contents of that directory to the root directory of your hosting provider’s server. For more information, please refer to mkdocs.org/user-guide/deploying-your-docs/.
Generating pages on the fly
As the project grows, it quickly becomes quite tedious to generate documentation pages manually and make a reference to relevant code snippets. To automate also this process, please refer to automatic code reference pages generation.
Summary
MkDocs
and mkdocstrings
are powerful tools for quick and straightforward code documentation generation. However, generated documentation quality strongly depends on the project’s structure and code docstrings written earlier. Taking a systematic approach to documenting your code will make the project documentation writing process considerably faster and eliminate frustration.
Full-stack data scientist. Aleksandra writes about topics that she finds interesting for software developers and scientists who are keen on technology. Fan of Polish dumplings with blueberries.