We are about to wrap up this tutorial on how to create a Cookiecutter template for an Android application running Kivy.
If you haven’t checked out Create your own Cookiecutter template and Extending our Cookiecutter template yet, please do so as this post draws on them.
The current project structure of Cookiedozer is as follows:
cookiedozer/
├── cookiecutter.json
├── {{cookiecutter.repo_name}}
│ ├── {{cookiecutter.repo_name}}
│ │ ├── {{cookiecutter.app_class_name}}.kv
│ │ ├── {{cookiecutter.repo_name}}.py
│ │ ├── __init__.py
│ │ └── main.py
│ ├── LICENSE
│ ├── MANIFEST.in
│ ├── README.rst
│ ├── setup.py
│ └── tests
│ └── test_{{cookiecutter.repo_name}}.py
├── cookiedozer01.png
├── cookiedozer02.png
├── hooks
│ └── post_gen_project.py
├── LICENSE
└── README.rst
Setting up Sphinx
Following the instructions of the ReadTheDocs tutorial, we are going to create a docs folder at the template level.
$ cd cookiedozer/\{\{cookiecutter.repo_name\}\}/
$ mkdir docs
Quickstart
Sphinx comes with a very handy CLI tool to set up docs named sphinx-quickstart.
$ cd docs
$ sphinx-quickstart
We can feed the Cookiecutter variables to it. Feel free to change the values according to your needs.
> Root path for the documentation [.]: <ENTER>
> Separate source and build directories (y/n) [n]: y
> Name prefix for templates and static dir [_]: <ENTER>
> Project name: {{cookiecutter.app_title}}
> Author name(s): {{cookiecutter.full_name}}
> Project version: {{cookiecutter.version}}
> Project release [{{cookiecutter.version}}]: <ENTER>
> Source file suffix [.rst]: <ENTER>
> Name of your master document (without suffix) [index]: <ENTER>
> Do you want to use the epub builder (y/n) [n]: <ENTER>
> autodoc: automatically insert docstrings from modules (y/n) [n]: y
> doctest: automatically test code snippets in doctest blocks (y/n) [n]: n
> 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]: n
> coverage: checks for documentation coverage (y/n) [n]: n
> pngmath: include math, rendered as PNG images (y/n) [n]: n
> mathjax: include math, rendered in the browser by MathJax (y/n) [n]: n
> ifconfig: conditional inclusion of content based on config values (y/n) [n]: y
> viewcode: include links to the source code of documented Python objects (y/n) [n]: n
> Create Makefile? (y/n) [y]: y
> Create Windows command file? (y/n) [y]: n
index.rst
Sphinx creates an index.rst
file inside of the source folder
which should look similiar to the following:
.. {{cookiecutter.app_title}} documentation master file, created by
sphinx-quickstart on Thu Jan 29 23:09:48 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to {{cookiecutter.app_title}}'s documentation!
======================================================
Contents:
.. toctree::
:maxdepth: 2
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
Adding more pages to the docs is fairly straightforward. You need to create another rst file and insert it to the table of contents respectively.
readme and app docs
We can reuse README.rst
from part 1 of this tutorial. We will also
create a separate file for our application.
$ cd source
$ touch readme.rst
$ touch {{cookiecutter.repo_name}}.rst
Open readme.rst
and insert the following code:
.. _readme:
.. include:: ../../README.rst
We instruct sphinx to render the contents of
{{cookiecutter.repo_name}}.rst
based on our Python source code:
{{cookiecutter.repo_name}} Package
==================================
:mod:`{{cookiecutter.repo_name}}` Module
----------------------------------------
.. automodule:: {{cookiecutter.repo_name}}.{{cookiecutter.repo_name}}
:members:
:undoc-members:
:show-inheritance:
Next up, we add the new pages to index.rst
and also instruct cooiecutter to
render the short_description
:
.. {{cookiecutter.app_title}} documentation master file, created by
sphinx-quickstart on Thu Jan 29 23:09:48 2015.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to {{cookiecutter.app_title}}'s documentation!
======================================================
{{cookiecutter.short_description}}
Basics
------
.. toctree::
:maxdepth: 2
readme
.. _apiref:
API Reference
-------------
.. toctree::
:maxdepth: 2
{{cookiecutter.repo_name}}
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
Package location
The autodoc extension needs to know where to find our package. It turns out
conf.py
already features an according example, so we have to insert the
folder two levels about source to the sys path:
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../..'))
Change doc style
If you have read the previous parts of this tutorial, you might have noticed the slightly different doc string style syntax. I generally prefer Google Style doc strings over regular sphinx, as they are slightly more readable and usually require less boilerplate.
In this particular case we will use the standard syntax though, so they seamingly integrate with Kivy’s docs. At the end of the day, it’s totally up to you which style you would like to use for your project.
You will need to install the Napoleon extension to be able to use the Google style doc strings with Sphinx.
Buildozer
Buildozer is yet another great tool developed by the Kivy team. As I mentioned right in the beginning of Create your own Cookiecutter, Buildozer is still in alpha-development stage with limited OS support. However it is working just fine though on Ubuntu 14.04 (Trusty Tahr) 64-bit. If you are using Windows or MacOSX you may want to check out this guide on the Kivy Android Virtual Machine.
Installation
Back when I set it up Buildozer on Ubuntu Trusty Tahr I followed this guide. The official Buildozer Docs feature a similar chapter on the installation process for older Ubuntu versions, namely Precise Pangolin and Saucy Salamander.
Buildozer itself does not require anything aside from Python, which means you don’t need to install any of the 32bit libraries and not even Cython, in order to create a spec for your template.
$ pip install --upgrade buildozer
Create spec file
Assuming you have successfully installed Buildozer, you can now run the
following command to create a spec file. It needs to be at the project root
(next to setup.py
):
$ cd ../..
$ buildozer init
ℹ️ As a side note, if you are using GitHubs gitignore file for Python projects
any *.spec
files are excluded from version control. So I’ll quickly add the
following line to Cookiedozers gitignore:
# Do not ignore buildozer.spec as it is required for our template
!buildozer.spec
Next up I open buildozer.spec
in a text editor and replace several values
with Cookiecutter variables. You may want to have a brief look at the
buildozer.spec of the game 2048 by Kivy core committer
@tito as it is a great example of what you actually need to set to
create a working Android apk.
For reasons of clarity and comprehensibility the following listings only contain the settings that are different from the defaults.
# (str) Title of your application
title = {{cookiecutter.app_title}}
# (str) Package name
package.name = {{cookiecutter.repo_name}}
# (str) Package domain (needed for android/ios packaging)
package.domain = {{cookiecutter.full_name|lower|replace(' ', '.')}}
# (str) Source code where the main.py live
source.dir = {{cookiecutter.repo_name}}
# (str) Application versioning (method 1)
version.regex = __version__ = ['"](.*)['"]
version.filename = %(source.dir)s/__init__.py
Once again I make use of Cookiecutters features to automatically transform the
author’s name to all-lowercase separated by a dot which will be the package
domain of our app. So Raphael Pierzina
ultimately becomes
raphael.pierzina
.
Find out more about advanced usage of Cookiecutter features in the documentation.
Build an apk
We are now able to create a deployable distribution of a project, which has been generated from the template.
The first time you actually run the according Buildozer command it will download a bunch of tools including the Android SDK and NDK. In other words don’t worry if it takes quite a while as it’s just this one time for all your Buildozer projects. See Buildozer Quickstart.
Go ahead and give it a try! 😉
$ buildozer -v android debug
Deploy to your Android device
Once you have enabled USB Debugging on your device, you can deploy with the following command:
$ buildozer android deploy logcat
Makefile
I personally find it very convenient to define aliases for commands, that I use frequently, in a Makefile:
Create a new file at the top level of the app:
$ touch Makefile
What you define in your Makefile
depends on your personal preference
really. As for my part, I constantly run the test suite and occasionally forget
the correct command to generate a html coverage report.
So it makes sense for me to add them 🙂
.PHONY: docs
help:
@echo "test - run the test py.test suite"
@echo "coverage - generate a coverage report and open it"
@echo "docs - generate Sphinx HTML documentation and open it"
@echo "apk - build an android apk with buildozer"
@echo "deploy - deploy the app to your android device"
test:
python setup.py test
coverage:
python setup.py test -a '--cov={{cookiecutter.repo_name}} --cov-report=html'
xdg-open htmlcov/index.html
docs:
$(MAKE) -C docs html
xdg-open docs/build/html/index.html
apk:
buildozer -v android debug
deploy:
buildozer android deploy logcat
I’m using xgd-open
to view the generated html files in Firefox, in case
your wondering. Other than that I implemented a help command and put it
right in the beginning of the file. Invoking make without any arguments runs
the first target, namely help
.
Yay! We made it. 👍
We created a fully-fledged Cookiecutter template for a Kivy app that features a pytest suite, sphinx docs and a Makefile. You can easily deploy the app to your favourite Android mobile device via Buildozer. Last but not least the application is an installable Python Package, with entry points set up, which you can even upload to PyPI.
You can find the latest version of the Cookiedozer template on GitHub!
Hope you liked this tutorial and it was useful to you. I would love to hear from you. Please send me feedback via twitter or email. Thank you! 👋