Best Documentation Generator Python

Documentation refers to various kinds of materials that describe a software, a piece of computer hardware, or an electronic device. Documentation supports a wide variety of activities, such as installation and configuration, replication of models and products, education, training, and maintenance.

Best Documentation Generator Python is one of the most exciting open source software development projects in the world today. The open source community has led to many fantastic presentations, conferences and events

In this post, we will talk about the best python documentation tools for better documentation. Python is a famous general-purpose programming language and extremely versatile. It has a simplest syntax that encourages the programmer to write readable code.

People usually don’t like technical documentation. They prefer just the code and never want to waste their time on manuals. The reason for this is simple — they don’t believe that manuals and technical documents are necessary. But coding is not easy, especially when you start working on a project on your own.

Project Documentation

README file at the root directory should give general information to both users and maintainers of a project. It should be raw text or written in some very easy to read markup, such as reStructuredText or Markdown. It should contain a few lines explaining the purpose of the project or library (without assuming the user knows anything about the project), the URL of the main source for the software, and some basic credit information. This file is the main entry point for readers of the code.

An INSTALL file is less necessary with Python. The installation instructions are often reduced to one command, such as pip install module or python setup.py install, and added to the README file.

LICENSE file should always be present and specify the license under which the software is made available to the public.

TODO file or a TODO section in README should list the planned development for the code.

CHANGELOG file or section in README should compile a short overview of the changes in the code base for the latest versions.

Project Publication

Depending on the project, your documentation might include some or all of the following components:

  • An introduction should give a very short overview of what can be done with the product, using one or two extremely simplified use cases. This is the thirty-second pitch for your project.
  • tutorial should show some primary use cases in more detail. The reader will follow a step-by-step procedure to set-up a working prototype.
  • An API reference is typically generated from the code (see docstrings). It will list all publicly available interfaces, parameters, and return values.
  • Developer documentation is intended for potential contributors. This can include code convention and general design strategy of the project.

Sphinx

Sphinx is far and away the most popular Python documentation tool. Use it. It converts reStructuredText markup language into a range of output formats including HTML, LaTeX (for printable PDF versions), manual pages, and plain text.

There is also greatfree hosting for your Sphinx docs: Read The Docs. Use it. You can configure it with commit hooks to your source repository so that rebuilding your documentation will happen automatically.

When run, Sphinx will import your code and using Python’s introspection features it will extract all function, method, and class sig

natures. It will also extract the accompanying docstrings, and compile it all into well structured and easily readable documentation for your project.

reStructuredText

Most Python documentation is written with reStructuredText. It’s like Markdown, but with all the optional extensions built in.

The reStructuredText Primer and the reStructuredText Quick Reference should help you familiarize yourself with its syntax.

Code Documentation Advice

Comments clarify the code and they are added with purpose of making the code easier to understand. In Python, comments begin with a hash (number sign) (#).

In Python, docstrings describe modules, classes, and functions:

def square_and_rooter(x):
    """Return the square root of self times self."""
    ...

In general, follow the comment section of PEP 8#comments (the “Python Style Guide”). More information about docstrings can be found at PEP 0257#specification (The Docstring Conventions Guide).

Commenting Sections of Code

Do not use triple-quote strings to comment code. This is not a good practice, because line-oriented command-line tools such as grep will not be aware that the commented code is inactive. It is better to add hashes at the proper indentation level for every commented line. Your editor probably has the ability to do this easily, and it is worth learning the comment/uncomment toggle.

Docstrings and Magic

Some tools use docstrings to embed more-than-documentation behavior, such as unit test logic. Those can be nice, but you won’t ever go wrong with vanilla “here’s what this does.”

Tools like Sphinx will parse your docstrings as reStructuredText and render it correctly as HTML. This makes it very easy to embed snippets of example code in a project’s documentation.

Additionally, Doctest will read all embedded docstrings that look like input from the Python commandline (prefixed with “>>>”) and run them, checking to see if the output of the command matches the text on the following line. This allows developers to embed real examples and usage of functions alongside their source code. As a side effect, it also ensures that their code is tested and works.

def my_function(a, b):
    """
    >>> my_function(2, 3)
    6
    >>> my_function('a', 3)
    'aaa'
    """
    return a * b

Docstrings versus Block comments

These aren’t interchangeable. For a function or class, the leading comment block is a programmer’s note. The docstring describes the operation of the function or class:

# This function slows down program execution for some reason.
def square_and_rooter(x):
    """Returns the square root of self times self."""
    ...

Unlike block comments, docstrings are built into the Python language itself. This means you can use all of Python’s powerful introspection capabilities to access docstrings at runtime, compared with comments which are optimized out. Docstrings are accessible from both the __doc__ dunder attribute for almost every Python object, as well as with the built in help() function.

While block comments are usually used to explain what a section of code is doing, or the specifics of an algorithm, docstrings are more intended towards explaining other users of your code (or you in 6 months time) how a particular function can be used and the general purpose of a function, class, or module.

Writing Docstrings

Depending on the complexity of the function, method, or class being written, a one-line docstring may be perfectly appropriate. These are generally used for really obvious cases, such as:

def add(a, b):
    """Add two numbers and return the result."""
    return a + b

The docstring should describe the function in a way that is easy to understand. For simple cases like trivial functions and classes, simply embedding the function’s signature (i.e. add(a, b) -> result) in the docstring is unnecessary. This is because with Python’s inspect module, it is already quite easy to find this information if needed, and it is also readily available by reading the source code.

In larger or more complex projects however, it is often a good idea to give more information about a function, what it does, any exceptions it may raise, what it returns, or relevant details about the parameters.

For more detailed documentation of code a popular style used, is the one used by the NumPy project, often called NumPy style docstrings. While it can take up more lines than the previous example, it allows the developer to include a lot more information about a method, function, or class.

def random_number_generator(arg1, arg2):
    """
    Summary line.

    Extended description of function.

    Parameters
    ----------
    arg1 : int
        Description of arg1
    arg2 : str
        Description of arg2

    Returns
    -------
    int
        Description of return value

    """
    return 42

The sphinx.ext.napoleon plugin allows Sphinx to parse this style of docstrings, making it easy to incorporate NumPy style docstrings into your project.

At the end of the day, it doesn’t really matter what style is used for writing docstrings; their purpose is to serve as documentation for anyone who may need to read or make changes to your code. As long as it is correct, understandable, and gets the relevant points across then it has done the job it was designed to do.

How to Set Up Your Python Project Docs for Success

Automate your document creation workflow with Sphinx and Read the Docs

You made an awesome piece of Python software and released it to the public. Great!Unfortunately, that’s not enough. ️You need documentation!

Good documentation is vital to adoption. Making clear docs is one of the nicest thing you can do for your current and future package users.

Docs don’t write themselves, but you can get part way there with Read the Docs, Sphinx, and some tears. Just kidding, there might be some complications, but hopefully, there won’t be any tears.

Setting up docs to build automatically on each new release can be confusing. In this article, I’ll show you how to set up your docs so you can give your project the best chance of success. Let’s go!

sphinx in the dessert
Sphinx. Source: pixabay.com

If you don’t have a basic working Python package, check out my guide to making one here. Then read the next article to learn how to add tests, Travis, Coveralls, Black, and PyUp so that you have more faith your code won’t break.

The example project I’ll use in this article is pybrariesa wrapper I made for the libraries.io API. You can use it to subscribe to email alerts for new versions of open source packages. You can also use it to find information about many aspects of open source packages and repositories. Here are the docs. Let’s see how to build them!

Step 1: Set up Read the Docs

Read the Docs (RTD) hosts open source project docs for free! It’s very cool. 🕶

Set up your Read the Docs account at https://readthedocs.org.

Then do the following:

  1. Import your GitHub repository manually if you don’t see it listed as available to access on RTD.
  2. Once you are in your project on RTD, enter the relevant information and check the box for Edit advanced project options.
  3. On the next screen choose Python for your Programming Language.
  4. Click Finish. Then Admin. Then Advanced Settings.
  5. Check the box for Install your project inside a virtualenv using setup.py install and enter requirements_dev.txt in the Requirements file field (assuming that’s the name of your requirements file. Save. Alternatively, you can create a readthedocs.yml configuration file as explained here.
settings

6. Click on the Builds tab. You should see that a build is in progress or completed.

7. When the build is completed, click on View Docs. These docs aren’t showing much info specific to our package yet — we’ll work on that in a moment.

When you push to GitHub your docs will build automatically if a webhoook is configured. If you automatically connected your repo to GitHub, you may not need to configure anything else for auto-builds.

If you manually imported your repo, you’ll need to set up a webhook. Instructions can be found here. I made minor improvements to these docs, so if you think something is unclear, improve them with a PR. Here’s how to add a webhook:

In your GitHub repo, go to Settings -> Webhooks -> Add webhook. You should see a form like the one below.

add webhook screenshot

For Payload URL, go to RTD’s Integrations setting and copy the webhook information. Prepend it with https://. You can leave everything else alone and click Add webhook. Or choose Let me select individual events if you want to trigger RTD doc builds in response to other GitHub events beyond pushes to the repo. FYI, I had to delete my webhook on RTD and GitHub and redo re-add the webhook to make it work.

Next time you push your code to GitHub and merge the PR, head to RTD. You should see that your docs were rebuilt automatically! 🎉 Give it a few minutes if you don’t see changes right away.

build history on RTD

Cool! Now let’s set up Sphinx to generate our documents for RTD.

Step 2: Install and Configure Sphinx

Sphinx claims to make it easy to create intelligent and beautiful Python documents. I don’t know that I’d say it’s a snap, but Sphinx is pretty cool. Features include syntax highlighting, themes, and easy document linking. Here’s the Sphinx getting started guide for reference.

Add sphinx==3.03 to requirements_dev.txt and install it with pip install -r requirements_dev.txt.

Other Sphinx. Source: pixabay.com

Create a docs directory in the top level of your project directory. In that directory, run sphinx-quickstart from the command line.

You will be asked a few questions. Enter the project name and author name when prompted. Generally the defaults are what you want.

The following files will be generated automatically:

  • index.rst
  • conf.py
  • Makefile

conf.py

conf.py controls how Sphinx runs when the docs are built. In it, you configure project documentation settings. Let’s make a few changes to conf.py to make Sphinx create better docs. Uncomment and adjust the section so the abspath is ..

import os
import sys
sys.path.insert(0, os.path.abspath('..'))

Insert the following into the list of extensions:

extensions = [
'sphinx.ext.napoleon',
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'sphinx.ext.coverage',
]

I’m not a fan of the alabaster template, so I added sphinx_rtd_theme==0.4.3 to my requirement_dev.py file and installed it.

If you do the same thing, change the line about html_theme in conf.py to this:

html_theme = ‘sphinx_rtd_theme’

Make

Make is a build automation tool. The Makefile that was generated by Sphinx controls how shortcut commands that start with make operate. Learn more about makefiles here. You can probably get by without digging deeply into Make. 😉

Run make html from the command line to create your docs with this one shortcut command. Then, in your docs->build_->html directory you should see index.html. Open the file in your browser and you should see your bare-bones docs. 😄

To check for any undocumented functions and classes, add the following lines to your Makefile.

%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -b coverage

The line-b coverage appended creates a coverage report so that can tell you how much of your code is documented. Now when you run make html, the html folder will contain a text file named python.txt. That will show you where you need some documentation. 😀

Commit and continue on to make your doc files.

Other docs. Source: pixabay.com

Step 3: Create Doc Files

You can choose whether to write your files in Markdown (hereinafter md) or reStructuredText (hereinafter rst). Md is closer to regular prose and faster to learn. However, rst allows you to use more of Sphinx’s powerful features. Here’s the GitHub guide to md and here’s the Sphinx guide to rst.

It’s your choice whether to invest the time in learning rst. There are about a billion other things you could learn, so if it isn’t at the top of your list, I get it. However, many project’s docs are written in rst, so it’s nice to know.

You can convert between snippets of md and rst quickly with this online pandoc converter. You can use it to copy-paste from one format to the other. CloudConvert does the same with whole files. CloudConvert starts charging after 25 minutes of use per day.

If you are going the rst route, switch your README file extension to .rst.

Also, setup.py will need the README name and long_description_content_type switched to rst.

I’m going to use rst. If you’re using md, change the file extensions below to .md.

Create the following files:

  1. CODE_OF_CONDUCT.rst
  2. CONTRIBUTING.rst
  3. HISTORY.rst
  4. README.rst

CODE_OF_CONDUCT.rst

Here’s GitHub info with a template code of conduct. The code of conduct explains how folks are expected to conduct themselves with regard to collaborating on your project and what to do if individuals are not acting appropriately. Add your email where the template has a place for it. If you want to copy the GitHub markdown template into rst, you can use one of the converters mentioned above.

CONTRIBUTING.rst

Make it easy for people who want to contribute to your project to do so. Put clear instructions in your contributing file. Feel free to use my file as a base.

HISTORY.rst

History will contain your changelog. It is helpful for package users. You can also use the contents in your release info on GitHub.

In history.rst add the following.

=======
History
=======0.0.1 (2020–05–15)
— — — — — — — — -* First release on PyPI.

Update the date to the appropriate date and add any other relevant bullet points. You’ll append the file as you make release new versions of your package.

README.rst

Your README should include install and basic use information. I suggest you point users to the full docs on RTD.

You can add other documents to your project, but make sure you put the file names in your index.rst’s TOC. Then they will show up and be linked to in your built docs.

Now let’s make sure our users can get help understanding what your functions and classes do.

papers stacked
Other Docs. Source: pixabay.com

Step 4: Add Docstrings

Docstrings are a method of communicating to your user how a class or function works. The docstrings will show up in your users’s code when they ask for help. Sphinx will take your docstrings and automatically make them usable in your docs on RTD, too.

Write your Docstrings in your code, immediately after the first line of your class or function. Docstrings start with triple quotes and should include any info your user might need, including information about parameters and return values.

Python doesn’t have one obvious way to format docstrings. Pick one way to write docstrings so they look neat and no one has to ask or think about how to do things.

I suggest using Google style — which is recommended for ease of writing and reading. A good discussion of docstring formatting can be found here.

Make sure you let your contributors know about your chosen docstring format by including instructions in your contributing file.

When you have docstrings in you code, you can then build your docs locally and see your docstrings in your browser. When the local version looks good, commit, push, and merge your PR to see your docstrings on RTD at your module page.

Strings without the docs. Source: pixabay.com

If things don’t work as expected, here are some suggestions to get you back on track:

Troubleshooting

Sphinx and RTD can break or cause docs to look different than expected for many reasons. Check the build logs in RTD to find errors.

Common problems include:

  • If you docs are not building and you are using rst files, there is likely invalid rst somewhere. To find invalid rst, run file contents through one of the rst checkers mentioned above.
  • If your docs build but your modules aren’t displaying, check the raw output logs on RTD for hints.
  • Make sure your setup.py and requirements_dev.txt files are correct.
  • If you need an environment variable for things to run add it in the RTD settings.

The RTD and Sphinx docs and Stack Overflow are helpful, but I’ve found this troubleshooting cumbersome. I feel your pain.

Now let’s look at a nicer topic — communicating information to prospective users via badges.

Step 5: Add Badges to README

Badges provide at-a-glance information to people interested in your project. Badges can instill confidence and legitimacy. Here’s an example of the badges that can sit atop your README:

badges

Many badges are available at https://shields.io/ and https://badgen.net/. I added some of mine from shields.io. To get the badge code, don’t just copy the url next to the badge. Click on the URL. Then append your package name. See the example below for the wheel badge.

badging screenshot

Then copy the md or rst code from the dropdown and paste it into your README.

Many badges are available at the website of the relevant app. PyUp, Travis, and Coveralls have badge code you can grab. For PyUp, if you click on the badge on your PyUp dashboard, you’ll then see the code you can copy and embed in your README.

pyup badge code

Here’s RTD’s info on badges.

Cool! We’re badged. Finally, let’s look at facilitating collaboration.

Step 6: Create Issue and PR Templates

Help from the larger community is a great benefit available to an open source project. You want to make it easy for your users to report bugs and feature requests with relevant information. A great first step is providing a clear issue template.

Issue Templates

In your browser, go to your GitHub repo ->Settings -> Options. Under Features, click the Green Set up templates button.

screenshot of set up issue templates

You can add a custom issue template or use one of the default templates from GitHub.

Pull request templates are similarly helpful. GitHub has a good guide to making one here.

Now it’ll be easier for your to get help with your open source project!

MkDocs & Material installation

MkDocs is a static site generator for building project documentation and together with the Material framework, it simply looks gorgeous. First, we need to install a heap of packages in order to use all of the functionalities of MkDocs. All of these packages are pip-installable.

Bonus Tools:

pdoc

Probably the second-most popular Python-exclusive doc tool (Doxygen is more general) it’s got 373 stars and 12 contributors. Its code is a fraction of Sphinx’s complexity and the output is not quite as polished, but it works with zero configuration in a single step. It also supports docstrings for variables through source code parsing. Otherwise it uses introspection. Worth checking out if Sphinx is too complicated for your use case.

pydoctor

A successor to the popular epydoc, it works only for Python 2. Main benefit is that it traces inheritances particularly well, even for multiple interfaces. Works on static source and can pass resulting object model to Sphinx if you prefer its output style. I actually prefer the clean look of Pydoctor to Sphinx, however.

doxygen

Not Python-exclusive and its interface is crowded and ugly. It claims to be able to generate some documentation (mostly inheritances and dependencies) from undocumented source code. Should be considered because many teams already know this tool from its wide use in multiple languages (particularly C++).

Conclusion

You have probably heard a lot about Python, the dynamic object-oriented programming language which is gaining immense popularity in recent years. You know that Python has a wide range of applications in scientific fields such as maths and physics, and game development.

While Python is one of the most readable programming languages, there will still come a time when documentation becomes necessary. Like in every other language, documentation for Python also has its limitations because you have to put a lot of effort into creating it.

Leave a Comment