Writing Documentation for Your Software⚓
Documentation serves different audiences and purposes. Good projects usually include several types of documentation.
Why Documentation Matters?
Good documentation is an essential part of professional software development. It makes your code understandable, usable, and maintainable — not only for others, but also for future you.
Types of documentation⚓
We will here talk about the most generic and basic types of documentation, those that each project should contain.
However, depending on your project and especially project type, you could add other documentation types. For example:
- CLI project: Add a man page (either to the user documentation or as a Unix man page)
- REST API backend project: Add an OpenAPI specification to document the endpoints (handled automatically by frameworks such as
fastapi
)
README⚓
The README is the front page of your project repository. It should include:
- A short project description
- Installation instructions
- Basic usage example
- Links to more detailed docs
- License, citation info, contact (for research code)
Depending on your project Git Forge, its language could vary (though Markdown is the standard and is always accepted), and it could have a flavour (i.e some extensions to the base language to add features to your basic README file). Check the documentation of your Git Forge on the subject.
Note
For example, this page is written in Markdown, but includes extensions like Mermaid to draw diagrams such as the git commit graphs in Git Essentials, an extension to show a clean table of content in the pages, etc.
User & Developer Guides⚓
These are more detailed documents explaining how to use the software in various contexts.
User documentation includes:
- How-to guides (e.g at least a getting started describing how to install and a basic example)
- Examples and tutorials (could be more advanced)
- Common pitfalls and troubleshooting
Developer documentation includes:
- How to contribute (very important to set the rules for contributors, see Collaborative Git Workflows)
- Architecture overview
- Dependency information
- Build/test instructions
API Documentation⚓
API docs describe functions, classes, modules, and methods: what they do, what inputs they take, and what they return.
This can be:
- Written manually
- Generated from docstrings using tools like Sphinx or MkDocs
Docstring Conventions⚓
In Python, docstrings are the main source of in-code documentation.
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Note
If your project uses type hints, you can skip the type definition from the docstring. Indeed, your documentation generator can be configured to parse them too.
There are 3 common conventions for writing docstrings:
Google Style⚓
1 2 3 4 5 6 7 8 9 |
|
Type Hints variant:
1 2 3 4 5 6 7 8 9 |
|
✅ Readable ✅ Supported by many tools
For more detailed documentation: Google Python Style Guide
NumPy Style⚓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Type Hints variant:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
✅ Common in scientific codebases
For more detailed documentation: NumPy Docstring Standard
reStructuredText (reST)⚓
1 2 3 4 5 6 7 8 9 |
|
Type Hints variant:
1 2 3 4 5 6 7 |
|
✅ Native to Sphinx
For more detailed documentation: reST Documentation
Documentation Generators⚓
You can generate full documentation websites from docstrings and Markdown/ReST files using:
Sphinx⚓
Sphinx is the most popular tool for Python API documentation.
- Uses reStructuredText (or Markdown via extensions)
- Works well with NumPy or Google-style docstrings via
sphinx.ext.napoleon
- Integrates with Read the Docs for live hosting
Install and Initialize⚓
1 2 |
|
Example conf.py
additions⚓
1 2 3 4 5 6 |
|
Note
You can add more extensions depending on the features you need for your documentation. Some are not native to sphinx and must be installed first. You could for instance use the Read the Docs theme (after installing the package):
1 2 3 4 5 |
|
# noqa: F401
is an instruction for the linters to not apply this rule to the line (here it's an unused import, but still necessary for sphinx to use the theme).
Build the docs⚓
1 2 3 |
|
Warning
When using autodoc
, the extension simply processes autodoc directives present in the doc files, and parse the source code accordingly. Those directives must be present in the doc files beforehand.
If you want to generate documentation files with fully setup autodoc directives, you can use the following command from your doc/
directory:
1 |
|
You can then include the root doc file created by this command inside your doc pages as a link (or part of the table of content). It will generally be called <api output dir>/<package name>.rst
.
Tip
To always include the uptodate version of your API to the documentation, you can modify the doc/Makefile
so it generates the API before each doc build. Add this on a new line:
1 2 3 |
|
MkDocs⚓
MkDocs is a simpler, Markdown-based tool focused on static site documentation.
- Easy to use
- Pure Markdown
- Beautiful themes like
material
Install and create docs⚓
1 2 3 4 |
|
Add API Docs (Optional)⚓
Use mkdocstrings
to generate API reference:
Add this to the mkdocs.yml
configuration file:
1 2 3 |
|
Add to a .md
file:
1 |
|
Build static site⚓
1 |
|
Comments in code⚓
Comments are an often overlooked and essential part of writing clean, understandable, and maintainable code. They help readers (including your future self) understand why certain decisions were made, what complex logic is doing, or how a particular block fits into the bigger picture.
Types of Comments⚓
Python supports two main types of comments:
Single-line Comments⚓
Use the hash symbol #
to write a comment on a single line or after a line of code:
1 2 3 4 5 |
|
✅ Tip: Avoid stating the obvious. Focus on the "why", not the "what".
Block (Multi-line) Comments⚓
Although Python doesn't have a special syntax for block comments, you can stack single-line comments:
1 2 3 4 |
|
Not Docstrings⚓
Comments are different from docstrings, which are string literals used for documentation inside functions, classes, and modules:
1 2 3 |
|
Best Practices⚓
✅ Do | ❌ Avoid |
---|---|
Explain why something is done, not what is obvious | Commenting every single line |
Keep comments short and to the point | Writing outdated comments |
Update or remove comments when code changes | Using comments to disable code permanently |
Use comments to explain complex or non-intuitive logic | Stating what the code clearly expresses on its own |
Write comments in English (or the language of your team/project) | Using slang or abbreviations that others might not understand |
Tools and Formatting⚓
- Linters like flake8 and ruff can warn about misplaced or excessive comments.
- Use a consistent style (e.g. one space after
#
) and keep lines under 79 characters. - Document assumptions, limitations, or workarounds clearly.
Summary⚓
Use comments to communicate intent, not just to describe the code. Good comments can reduce onboarding time, ease debugging, and improve team collaboration — but bad or stale comments can mislead just as easily.
Hosting and Live Documentation⚓
You can host your generated documentation using:
- GitHub Pages (
mkdocs gh-deploy
) - GitLab Pages
- Read the Docs (for Sphinx projects)
- Self-hosted HTML
Read the Docs can be setup to automatically build and publish the doc whenever the online git repository is changed. For the other options, it can also be automatized via CI/CD.
Best Practices⚓
- Keep README up to date and focused
- Write docstrings for every public function/class/module
- Use consistent docstring style
- Generate and preview your docs as part of CI
- Document corner cases, expected input types, and errors
- Include examples and diagrams when possible