Sphinx Autodoc Tutorial for Dummies

I recently installed Sphinx and spent the better part of a day trying to get it to work. And not because it was hard (it actually came with a “d’oh!” moment at the end), but rather because I found the Sphinx tutorial rather obscure. This tutorial is going to show how to use Sphinx to autodocument your modules.

It’s actually really easy. Follow these steps, and you can’t go wrong.

Install Sphinx.

easy_install -U Sphinx

easy_install comes with the Python installation (2.7) and can be found in the Scripts subfolder (C:\Python27\Scripts). This is also where the sphinx-quickstart script will be added.

Create a documentation directory.

Get started by running

sphinx-quickstart

You’ll enter a number of options now. In most cases you can simply click ENTER, and Sphinx will select the default options. I’ve highlighted some things you want to pay attention to:

  • Root path for the documentation. Where you want your files to be. I created a “docs” subfolder in my main project, so it doesn’t clutter up my project.
  •  autodoc: automatically insert docstrings from modules (y/N) [n]: Click Yes Here
  • Be sure to create a makefile. It makes life simple.

You can pretty much go with the default options, other than autodoc. Sphinx will generate an empty project in the path you specified, with a default index.rst file. This will be the root of your project – all other files will be accessed through it. At this point, the basic structure already works. Compile it by running the makefile generated by the sphinx-quickstart script.

make html

The generated html files will be in your specified path/_build/html.

Autodoc, roll out!

In order for sphinx to be able to document your python code, it needs to find it first. Open the generated conf.py file in your specified path. Add the following line (with the path of your Python source). Make sure to use Python string formatting as shown!

sys.path.insert(0,"C:\\workspace\\PyPlotStatistics\\src")

You can also use the following notation for a relative directory. abspath will make the path absolute and fix up the formatting as well.

os.path.abspath('mydir/myfile.txt')

Adding notation

Open index.rst. The blank file should look like this:

Contents:

.. toctree::
   :maxdepth: 2

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

Add the name of one of your python modules and an example class, located in your specified source path. The index file should look like this:

Contents:

.. toctree::
   :maxdepth: 2

.. automodule:: SomeModuleName

.. autoclass:: SomeClassName
    :members:

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

Run make html again to rebuild. Sphinx should automatically identify your module and add a reference to SomeModuleName and SomeClassName. These references will also appear in the index. The clause :members: specifies that all members of the class will be documented, so you don’t have to write in each function manually.

Expanding the Table of Contents

At this point you can add other files and modules to create the documentation the way you like. Make sure all additional files are in the format you specified (default is *.rst), and in your sphinx documentation directory. For instance, if you were to move your module documentation into a file called code.rst, the expanded index might look like this:

Contents:

.. toctree::
   :maxdepth: 2

   installation.rst
   code.rst

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

Troubleshooting

Python modules / files don’t appear in the documentation.

  1. Sphinx documentation works with alignment. Make sure the indentation is exactly as shown in both previous examples, so that all the items in the table of contents are exactly aligned. This is an easy one to miss.
  2. Check the path in sys.path, maybe by printing it out yourself. Is the formatting correct? Is the path accurate?
  3. Have you typed in the module / class name correctly (case and all)?

I can see my class, but it doesn’t show any / some of the functions.

Function documentation should look like the example and be indented properly as well, otherwise sphinx won’t recognize it.

"""
Created on 29 July 2012
@author: Lisa Simpson
"""

class DatabaseManager(object):
    """
    Create and manage a new sqlite database.
    """

I don’t feel like putting in all my files manually!

Neither do I! The next section is for you…

Saving Time With APIdoc

APIDoc is a tool that comes with sphinx and is designed to automatically pull documentation out of your entire project, automatically creating *.rst files for each module. You can find the apidoc scripts in the Python2X/Scripts directory with the other sphinx scripts.

sphinx-apidoc [options] -o <outputdir> <sourcedir> [pathnames ...]

Options and pathnames are optional, but the full explanation of all the options can be found in the sphinx apidoc documentation. Apidoc is a simple script which instantly generates all your project documentation.

Numpydoc

Tutorial expanded! Learn how to add numpydoc to Sphinx, and what it gives you…

SQLite Python Tutorial

Found a great tutorial for getting started with sqlite. Versions of Python over 2.5 have sqlite included automatically, so no additional installations this time, for a change 🙂

Check out SQLite Python Tutorial at zetcode.com.

List Slicing (last index minus 1)

Stupid bug caused because I didn’t remember this very simple fact! Suppose we have a list:

mylist = [1,2,3,4,5]

And we want to slice only the first two elements: [1,2].
Writing this:

print mylist[0:1]

will actually only give us this:

[1]

If we want to print the first two elements, we need to write

print mylist[0:2]

and then we get

[1,2]

because Python always selects the last index minus 1.

Sort complex objects by index

Here’s a quick and elegant way to sort complex objects in Python (for instance, a list of lists or a 2D array), using the objects’ indices as the key. Sorting by the second column:

Input:

data = [ [5, 7, 3],
         [4, 2, 2],
         [0, 3, 5],
       ]

Code:

data = sorted(data, key=lambda x: x[1])

The lambda keyword lets us define a mini-function which receives x (in this case, our row) and returns the second element of x (x[1]).

Output:

[[4, 2, 2],
 [0, 3, 5],
 [5, 7, 3]]

Activate cmd in specific folder

Activating cmd is pretty quick through the Run command, but then you usually have to type in the path you want it to run in – time consuming if you have several different folders or a long path.

OR,

Shift-Rightclick on the folder you want cmd to run. An Open command window here option will appear, which doesn’t normally show up. Magic!

Make Eclipse launch from a specified workspace

I couldn’t seem to make eclipse launch from the workspace I was using. No matter how I tried setting the defaults, it simply would not load from the last workspace used, and kept reverting to the default workspace (which was empty).

Rather than using Switch Workspace all the time (which is a pain, because it restarts Eclipse each time), it’s quicker just to change the configuration file.

This file is called config.ini and you can find it in the configuration directory of your Eclipse installation:

osgi.instance.area.default=C\:\\Workspace

Change the default value of this row to the path of your workspace.


Alternatively, you can run Eclipse from the command line using the -data tag, which lets you manually choose the desired workspaces.

eclipse -data C:\Workspace

How to Change Eclipse Workspace

How to change an Eclipse Workspace?

Using Eclipse 3.7 (Indigo) over Windows 7, this method works for me:

File -> Switch Workspace -> Other. Type in new workspace name. Once in the new workspace, click File -> Import… and under General choose “Existing Projects into Workspace. Press the Next button and then Browse for the old projects you would like to import. Check “Copy projects into workspace” to make a copy.

The next option *should also* work, but it doesn’t seem to work on my computer. Eclipse voodoo?

Try Preferences -> General -> Startup and Shutdown -> Workspaces. Make sure that the “Prompt for workspace on startup” box is checked. Close  Eclipse and reopen. You should be prompted for the workspace on startup.

Let me know if this works for you, and if so, how!


After transferring the workspace, make sure your compilers are still working and the library paths haven’t changed. I had to reconfigure my Python interpreter, but the C++ CDT compiler seemed to survive the transfer okay.