Documenting Python Code with Sphinx

Well, it’s been a while.

While silent here, I’ve definitely been busy elsewhere. Follow me on github to see the work I’ve been doing with the Maya API and Py.Qt. Also find me on vimeo for demos of some of the stuff I’ve been working on.

Anyways though, I’ve been meaning to address my WordPress for some time now, so what better way than to document my newly-learned skill of automatically creating documentation from docstrings using Sphinx!

Check out the Docs I created for some of my GitHub projects as an example.

Install

Installing Sphinx is a pretty straightforward task. First of all, make sure Python is in the Path for your command prompt. If you type Python and hit enter and it gives you an error, you know it’s not. If it’s not, make sure to add the file path to the file that contains python.exe into your system’s Path environment variable.

In your favorite command prompt, navigate to the folder you have python installed on (probably something like C:\Users\Benjamin\Python\Scripts). If you open that folder in explorer, you should see an application there called easy_install. In your command prompt, while in the ~\Python\Scripts directory, run: easy_install sphinx

Python will do its thing and lots of new files will be created in the Sphinx directory (can you tell I don’t come from a computer science background yet?). You’re good to go!

Setting up a Sphinx Doc

Setting up a document in Sphinx is pretty easy too. Navigate to a folder in your command prompt and create a new folder (md folderName if you’re using the command prompt). Run the command sphinx-quickstart and it will give you lots of instructions to follow. Most of them are pretty self explanatory, but if you don’t know what some of them do just leave it at its default. You can go back and change them later.

C:\Users\Benjamin\Desktop>md sphinxTutorial

C:\Users\Benjamin\Desktop>cd sphinxTutorial

C:\Users\Benjamin\Desktop\sphinxTutorial>sphinx-quickstart
Welcome to the Sphinx 1.6.6 quickstart utility.

Some notable settings that we can set here that will save us some time later are saying y to the query:

> autodoc: automatically insert docstrings from modules (y/n) [n]: y

This will enable us to generate our documentation into html automatically using special “docstrings”.

Setting Up a Python File for Sphinx Documentation

Besides your regular #comments, docstrings are a special type of string that Sphinx can interpret and convert into professional-looking html. According to python.org, a docstring is “a string literal that occurs as the first statement in a module, function, class, or method definition.”

Here’s an example:

def pointInCone(meshDag, p0):
    “””Determines if/the factor by which a point is inside a polygon cone; i.e. a “Search Cone”

    :param meshDag: The dag path of a polyCone object
    :param p0: A world space vector representing the point to check
    :type meshDag: MDagPath
    :type p0: MVector
    :return: The factor by which the point is in the cone or False if it is not
    :rtype: float, False
    “””

# rest of function

It might look like a lot’s going on there, and there is some syntax to be aware of, so let’s break it down.

  • The triple quoted string must go directly after you declare a function. In PyCharm, if you make one it will automatically make the :param: and :return: bits for you.
  • The description for the function goes directly after the triple quote.
  • A blank line separates the description and the parameter descriptions.
  • :param param1: Description of parameter   (How to declare an argument)
  • :type param1: object type   (How to declare that argument’s type)
  • :return: What it returns 
  • :rtype: return type

Pretty self-explanatory, right? You could obviously go way more in depth with these so read up on the Sphinx docstring syntax if you want to learn more.

Besides your docstrings, you also need to make sure your Python file won’t do anything or throw any errors when it runs. Part of this (or at least my workaround) involves surrounding all your imports with Try/except ImportError statements, because many of the maya-specific modules I’m importing aren’t recognized by Sphinx when it goes to parse the file.

Here’s what the end result of the above code gives us in the end:

point in cone result

Setting Things up for Documentation

Okay! Now to actually make our documents. In your Sphinx project folder, find the python file called conf.py   and open it up. The first thing we need to do is make sure our python package is in Sphinx’s path, so add the line sys.path.insert(0, os.path.abspath(r”fullPathToPythonPackage”))

  • notice the raw string formatting we used with the r”” in front of the string

Next, if you forgot to do this in the setup, make sure you have “sphinx.ext.autodoc” in the extensions array in the conf.py file.

Automating the Documentation

Okay! So now we’re ready to do some documentation!  Create a new rst file called something like code.rst  … In it, give it a heading. This is the name that it will be given in our contents tree later.

example:

Code Docs
—————-

Notice the underline under the words. Think of it like an html heading. Different symbols like === or surrounding it on both the top and bottom with symbols will give it different weights in the end.

Finally, we’re going to do what Sphinx was meant to do: autodocs!

*A simple search cone algorithm using vector angles*

.. automodule:: bm_pointInCone
   :members:

 

  • In rst format, surrounding text with * with make it italics, and ** will make it bold.
  • After a blank line, we’re saying here that we want Sphinx to run the automodule script on the bm_pointInCone module. Remember when we gave it the full path to its package? That’s why.
  • Using the :members: tag will make documentation for any method in the module that contains docstrings.
  • rst file formats use 3 spaces for tabs instead of 4

 

Classes are pretty much the same; here’s a basic example:

.. autoclass:: bm_spaceSwitcher_ui.SpaceSwitcherUI
   :members:

   .. automethod:: __init__

 

  1. Running autoclass on a class on a module we imported
  2. Making docs for every method that has docstrings on it
  3. Forcing Sphinx to make a doc for the __init__ method using the .. automethod:: function.

Finally, if you want to include a block of code in your rst file (which will eventually become a webpage), you can use:

.. code-block:: python

   import maya.cmds as cmds
   import maya.OpenMayaUI as omui

Notice the blank line after declaring the code block.

 

Adding Docs to our Webpage

Now that we’ve made our rst file, go to your index.py file. You’ll find code that says

.. toctree::
   :maxdepth: 2
   :caption: Contents:

  • toctree stands for Table of Contents Tree
  • With a max depth higher than one, your contents will expand if it has anything underneath it.

Skip a line and add the name of the rst file we made with all our automodule:: stuff in it.

.. toctree::
   :maxdepth: 2
   :caption: Contents:

   code

 

Creating the html webpage

It’s as simple as opening up your command prompt again while in the sphinx project directory (C:\Users\Benjamin\Desktop\sphinxTutorial) and running make html 

This will put your web files in the _build folder Sphinx has. Under _build/html you’ll find your index.html file. That’s the “homepage” file. Double click it and see what it looks like 🙂

Don’t like the look? Want it to be mobile-ready? Download and install the readTheDocs theme.

 

Publishing on GitHub

Okay, so now you want people to actually  be able to see your docs. GitHub has a nice Pages feature that allows you to create webpages for either your entire profile or for a single repo.

If you’re doing it for a single repo:

  1. Create a /docs folder
  2. Put the contents of the  _build/html folder in there.
  3. ***index.html must be in the root of the /docs folder for GitHub to build the site. ***
  4. Create a blank .nojekyll file in the /docs folder so that GitHub won’t ignore the folders that Sphinx made that start with an _
  5. Publish and wait! It sometimes takes around half an hour or so to see the result published. Go for a walk. You’ve been sitting for too long!

 

If you’re doing it for your username.github.io page:

  1. Put the contents of the _build/html folder in the root of your project repo. For user pages, GitHub requires the index.html file to be in the root of the repo.
  2. Create a blank .nojekyll file in the root of the repo so that GitHub won’t ignore the folders that Sphinx made that start with an _
  3. Publish and wait! It sometimes takes around half an hour or so to see the result published. Go for a walk. You’ve been sitting for too long!

 

That’s it! Again, check out my (work in progress) GitHub Page if you want to see what you can do with Sphinx.

Take care!

Ben

 

Advertisements
Image

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s