How to Document Django Applications with Sphinx

In this post I go over how to automatically document Django applications. By this I refer to a way to run a tool that automatically reads your projects and docstrings and generates beautiful documentation. Sphinx is an excellent tool for the job. Sphinx makes it easy to create beautiful intelligent documentation for projects. It uses reStructuredText as its markup language. Here’s how to go about it.

First install Sphinx using the command:

pip install sphinx

Initialise Sphinx

sphinx-quickstart

You will be asked several questions which will be used to generate a configuration file, a few folders and possibly a Makefile. You will want to make sure you enable autodoc to allow generating documentation from docstrings as well as the generation of Makefile so that you can run the make command in the future to update documentation. Below is an example of the what the screen looks like for these

Welcome to the Sphinx 1.6.1 quickstart utility.

Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).

Enter the root path for documentation.
> Root path for the documentation [.]: ./docs

You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> Separate source and build directories (y/n) [n]: n

Inside the root directory, two more directories will be created; "_templates"
for custom HTML templates and "_static" for custom stylesheets and other static
files. You can enter another prefix (such as ".") to replace the underscore.
> Name prefix for templates and static dir [_]: 

The project name will occur in several places in the built documentation.
> Project name: Your Project Name
> Author name(s): Some Author Name

Sphinx has the notion of a "version" and a "release" for the
software. Each version can have multiple releases. For example, for
Python the version is something like 2.5 or 3.0, while the release is
something like 2.5.1 or 3.0a1.  If you don't need this dual structure,
just set both to the same value.
> Project version []: 0.1
> Project release [0.1]: 

If the documents are to be written in a language other than English,
you can select a language here by its language code. Sphinx will then
translate text that it generates into that language.

For a list of supported codes, see
http://sphinx-doc.org/config.html#confval-language.
> Project language [en]: 

The file name suffix for source files. Commonly, this is either ".txt"
or ".rst".  Only files with this suffix are considered documents.
> Source file suffix [.rst]: 

One document is special in that it is considered the top node of the
"contents tree", that is, it is the root of the hierarchical structure
of the documents. Normally, this is "index", but if your "index"
document is a custom template, you can also set this to another filename.
> Name of your master document (without suffix) [index]: 

Sphinx can also add configuration for epub output:
> Do you want to use the epub builder (y/n) [n]: 

Please indicate if you want to use one of the following Sphinx extensions:
> autodoc: automatically insert docstrings from modules (y/n) [n]: y
> doctest: automatically test code snippets in doctest blocks (y/n) [n]: y
> intersphinx: link between Sphinx documentation of different projects (y/n) [n]: y
> todo: write "todo" entries that can be shown or hidden on build (y/n) [n]: y
> coverage: checks for documentation coverage (y/n) [n]: y
> imgmath: include math, rendered as PNG or SVG images (y/n) [n]: y
> mathjax: include math, rendered in the browser by MathJax (y/n) [n]: 
> ifconfig: conditional inclusion of content based on config values (y/n) [n]: 
> viewcode: include links to the source code of documented Python objects (y/n) [n]: 
> githubpages: create .nojekyll file to publish the document on GitHub pages (y/n) [n]: 

A Makefile and a Windows command file can be generated for you so that you
only have to run e.g. `make html' instead of invoking sphinx-build
directly.
> Create Makefile? (y/n) [y]: 
> Create Windows command file? (y/n) [y]: n

Creating file ./docs/conf.py.
Creating file ./docs/index.rst.
Creating file ./docs/Makefile.

Finished: An initial directory structure has been created.

You should now populate your master file ./docs/index.rst and create other documentation
source files. Use the Makefile to build the docs, like so:
   make builder
where "builder" is one of the supported builders, e.g. html, latex or linkcheck.

Upon completion, a docs file should appear in your project.

Generate HTML Documentation

You can then generate documentation in HTML format by changing to the docs folder and running the following command:

make html

You should see something like:

Running Sphinx v1.6.1
making output directory...
loading pickled environment... not yet created
loading intersphinx inventory from https://docs.python.org/objects.inv...
intersphinx inventory has moved: https://docs.python.org/objects.inv -> https://docs.python.org/2/objects.inv
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 1 source files that are out of date
updating environment: 1 added, 0 changed, 0 removed
reading sources... [100%] index                                                                                                                              
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
writing output... [100%] index                                                                                                                               
generating indices... genindex
writing additional pages... search
copying static files... done
copying extra files... done
dumping search index in English (code: en) ... done
dumping object inventory... done
build succeeded.

Build finished. The HTML pages are in _build/html.

Document Project Modules

Now we will tell Sphinx to document the modules of one of our applications.

Open docs/conf.py

After the first block of comments, add the following code so that Sphinx can read docstrings from project files:

import os
import sys
import django
sys.path.insert(0, os.path.abspath('..'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'yourprojectname.settings'
django.setup()

Next, create a modules folder within docs. We will use these to hold our documentation. E.g. To document models, create a file at modules/models.rst.

Edit models.rst and add the following content:

Models
======
.. automodule:: yourappname.models
    :members:

Save and close the file.

Next, make this link available in the documentation index by editing docs/index.rst.

Find the section starting with .. toctree:: and add a line modules/models under it so that it looks like this:

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

   modules/models

Save and close the file.

Now is the time to regenerate the documentation.

Run the following command from inside the docs folder.

make html

You can access the documentation by opening docs/_build/html/index.html in a browser. You should see ‘Models’ under ‘Content’.

That’s it!

If you want to be able to access your documentation from the Django application itself, e.g. using a link like /docs/, you can do this using the awesome django-docs package.

Enjoy.

Reference

1. Documenting your Django application with sphinx. https://madradavid.com/documenting-your-django-application-sphinx/.

How to Set Environment Variables with uwsgi

You can add env declarations in your uwsgi ini files as follows:


[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /project/path
# Django's wsgi file
module          = project.wsgi
# the virtualenv (full path)
home            = /home/someuser/.virtualenvs/project

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /project/path/nhs.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 664
# clear environment on exit
vacuum          = true

env             = DJANGO_CONFIGURATION=SomeConfig

You can add multiple env declarations if you want to declare several parameters

Reference

https://coderwall.com/p/93jakg/multiple-env-vars-with-uwsgi

How to use PostgreSQL with Django on OS X

In this tutorial I’ll describe how to use PostgreSQL with Django running on OS X.

First, install PostgreSQL. You can do this using several methods. For this tutorial we use brew by running the following command in a terminal:

    brew install postgresql

Next, start the PostgreSQL server by running the following command:

    postgres -D /usr/local/var/postgres

Note: For information on how to make PostgreSQL start automatically run the command:

    brew info postgres

Now we’ve started postgress, we can create a database called myproject by running the following command:

    createdb myproject

Next, log into the Postgres session in the terminal by running

    psql myproject

Then create a user for the project using the command:

    CREATE USER myprojectuser WITH PASSWORD 'password';

Next, set encoding, transaction isoloation (to block reads from uncommitted transactions) and timezone using the following commands:

    ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
    ALTER ROLE myprojectuser SET default_transaction_isolation \
 TO 'read committed';
    ALTER ROLE myprojectuser SET timezone TO 'UTC';

Next, grant the db user privileges with the command:

    GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;

Exit the SQL session using the command:

    Ctrl D

Now we are going to install Django. I assume you have virtualenvwrapper installed.

Create your new virtual environment using the command:

    mkvirtualenv myprojectenv

This creates and switches to the new environment.

In here we then install Django and Psycopg2 using the commands:

    pip install django psycopg2

Next, create a folder at a suitable location for your project using the commands:

    mkdir ~/myproject
    cd $_

Then create a Django project in the created folder using the command:

    django-admin.py startproject myproject .

Next, we need to tell Django to use Postgres since it uses SQlite by default. Open myproject/settings.py with your favourite editor.

Find the lines:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }

And change it to

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'myproject',
            'USER': 'myprojectuser',
            'PASSWORD': 'password',
            'HOST': 'localhost',
            'PORT': '',
        }
    }

Now we shall migrate the database using the following commands:

    python manage.py makemigrations
    python manage.py migrate

Note: On running the first command you may see an output saying No changes were detected. Ignore it.

You may now create a superuser using the command:

python manage.py createsuperuser

Now that is done, you may start your server using the command:

    python manage.py runserver 0.0.0.0:8000

That’s it! You can now view your site by visiting http://localhost:8000 in your browser. You should see the default index page. Using the admin credentials you created earler, you should be able to log in to the admin at http://localhost:8000/admin

Sources

How To Use PostgreSQL with your Django Application on Ubuntu 14.04 | DigitalOcean. https://www.digitalocean.com/community/tutorials/how-to-use-postgresql-with-your-django-application-on-ubuntu-14-04

PostgreSQL: Documentation: 9.4: PostgreSQL 9.4.5 Documentation. http://www.postgresql.org/docs/9.4/static/index.html

How to fix error of missing zip decoder in Django with Ubuntu 14.04

If installing Django on Ubuntu 14.04 and you run into an error like “IOError: decoder zip not available” solve it as follows:

Install libzip and create a symbolic link in /usr/lib using the commands:

sudo apt-get install zlib1g-dev
sudo ln -s /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/libz.so

Next, reinstall PIL using the commands while in bosg virtual environment:

pip uninstall PIL
pip install  --no-cache-dir PIL --allow-external \
PIL --allow-unverified PIL

Finally, refresh project if on producion environment.

How to fix error Ascii codec can’t encode unicode character in Django on Ubuntu

In this article I will discuss how to fix error messages saying Ascii codec can’t encode some unicode character when setting up Django on Ubuntu.

A solution is to change the LANG and to set the LC_ALL environment variables.

So, edit /etc/apache2/envvars

Change

LANG=C

to

LANG='en_US.UTF-8'

Also add the following:

LC_ALL='en_US.UTF-8'

How to fix problem of decoder jpeg not available

When doing image manipulation with PIL in a Django app, you may see an error like decoder jpeg not available.

To fix this on os X, first you need to install libjpeg as follows:

brew update
brew install libjpeg libpng

Next, try to reinstall PIL. Use the following command:

pip install  --no-cache-dir PIL --allow-external PIL --allow-unverified PIL

That should be all. However, if you get an error saying cc command failed while installing freetype, then you will need to install freetype2 as follows:

brew install freetype2

Next you need to create a symbolic link to allow pip find freetype2 as follows:

ln -s /usr/local/Cellar/freetype/2.6.1/include/freetype2\
 /usr/local/include/freetype

Note: 2.6.1 above is the version as at the time I ran the command. Replace it with the appropriate number for you.

Troubleshooting

If you do the above steps and still get the error, then uninstall the version installed via pip and build PIL from source. I had to do this once. Here’s code to see the decoders available

import _imaging
dir(_imaging)

See if jpeg_decoder is among the properties