Everyone knows that you should write documentation for your code. Writing documentation actually is not that hard. Like any type of writing, the hardest part is beginning. So how do you begin writing documentation for your Python projects?
Sphinx is the de-facto standard in the Python community for generating documentation for your projects. It's simple to create HTML/PDF files with code samples, tables of contents, and built in search. Many popular projects host their Sphinx docs on readthedocs.org. A couple of good examples are celery and flask.
One of the key feature of Sphinx is that it allows you to generate as much of the documentation as possible from comments in your Python code. It can also automatically pull the signatures of your modules, classes, functions and methods. Together, these features allow you to keep most of your documentation up to date automatically. Of course, you will also want to write higher level pages on specific topics, and you can easily define those in either Markdown or reStructuredText, both of which render as rich text when viewed directly in your GitHub repository.
First, you need to install Sphinx. Then you run their quickstart command, which prompts you for configuration options. You're pretty safe use the defaults in most cases. The only sphinx-quickstart options I typically customize are enabling autodoc and using "docs" as the project root.
Here are the basic console commands. You would run these from inside your project root.
sudo pip install sphinx sphinx-quickstart cd docs make html open _build/html/index.html
This will be sufficient to get a basic HTML document. Typically my next steps will be to integrated with my project README, and configure autodoc to find my code.
I usually have my READMEs defined in Markdown, but for the purposes of Sphinx I think it's worth it to switch to reStructuredText, simply so that you can include the README as the first page of your docs. reStructuredText is pretty simple, here is a quick example of a
README.rst to get you started.
=========================================== IPython: Productive Interactive Computing =========================================== Overview ======== Welcome to IPython. Our full documentation is available on `our website <http://ipython.org/documentation.html>`_; if you downloaded a built source distribution the ``docs/source`` directory contains the plaintext version of these manuals. If you have Sphinx installed, you can build them by typing ``cd docs; make html`` for local browsing. Instant running =============== You can run IPython from this directory without even installing it system-wide by typing at the terminal:: python -m IPython
This example illustrates how to format titles, subtitles, links, inline code and code blocks.
docs/index.rst file to include the README:
.. include:: ../README.rst
If that's all that's in your index file, and you run
make html again, you should see your README contents.
Next, we will start breaking out our documentation into multiples files. Simply create a new reStructuredText file along side
index.rst. You can call it anything, for example
example.rst. You can then include this file in your index like so:
.. include:: ../README.rst Read More --------- .. toctree:: :maxdepth: 2 example
This tells Sphinx to render your README, followed by a subtitle of "Read More", followed by a list of other documents, one of which is your external
example.rst, you could put the following.
Some Examples ============= Here are some examples to get you started. .. automodule:: src.examples :members:
This will look at your code in
src/examples.py for classes, functions and methods. Each one will be listed in this section of the docs, along with any docstrings that where present. See the following example. All of these sections in the text are optional.
def public_fn_with_sphinxy_docstring(name, state=None): """This function does something. write as much as you want here here is a code sample: >>> from example import public_fn_with_sphinxy_docstring >>> public_fn_with_sphinxy_docstring( ... 'foobar', ... 'pending') 0 :param name: The name to use. :type name: str. :param state: Current state to be in. :type state: bool. :returns: int -- the return code. :raises: AttributeError, KeyError """ return 0
If you use Jenkins for your continuous integration system, you can use the HTML Publisher Plugin to automatically build the documentation every time you merge. It will also host the HTML for you, right in Jenkins.