Cookiecutter

Every Python project is different, but they often share common elements. They will usually have a file with a list of required dependencies and some test files. A web application will need a “main” file that starts up everything and a folder for static files.

And since thousands of developers wrote a Django/Flask application or published a Python package, some people came with an idea to extract common parts of typical applications into a reusable “scaffolding”.

cookiecutter

That’s how the cookiecutter project was born.

Cookiecutter is a tool that lets you create a Python project from existing templates. Actually, it’s not limited to Python - there are templates for Java and PHP projects, Sublime Text plugins, and more.

You start by selecting an existing template, for example, a Flask website or a Python module. Then cookiecutter will ask you a couple of questions to customize the scaffolding. For example, you can choose which database you want to use (and based on your choice, it might already install the DB driver for you), how to name your project, what’s the license, etc. Finally, it will generate the scaffolding of a project for you.

How to use cookiecutter?

Install it with pip (or even better with pipx):

$ pipx install cookiecutter

Find a template that you want to use - a good list of popular ones is published directly in the cookiecutter repo: https://github.com/cookiecutter/cookiecutter#a-pantry-full-of-cookiecutters

Let’s take the first one on the list - a template called cookiecutter-pypackage: @audreyr’s ultimate Python package project template.

To use it, run the following command:

$ cookiecutter https://github.com/audreyr/cookiecutter-pypackage

Answer a few questions:

full_name [Audrey Roy Greenfeld]: Sebastian Witowski
email [audreyr@example.com]: sebastian@switowski.com
github_username [audreyr]: switowski
project_name [Python Boilerplate]: Python workshop example
project_slug [python_workshop_example]:
project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]:
pypi_username [switowski]:
version [0.1.0]:
use_pytest [n]: y
use_pypi_deployment_with_travis [y]:
add_pyup_badge [n]:
Select command_line_interface:
1 - Click
2 - Argparse
3 - No command-line interface
Choose from 1, 2, 3 [1]: 1
create_author_file [y]: y
Select open_source_license:
1 - MIT license
2 - BSD license
3 - ISC license
4 - Apache Software License 2.0
5 - GNU General Public License v3
6 - Not open source
Choose from 1, 2, 3, 4, 5, 6 [1]: 1

And voilá - your project’s scaffolding has been generated!

Let’s look at what’s inside:

TODO: Add this folder to github, so I can show what’s inside

python_workshop_example/
├── AUTHORS.rst
├── CONTRIBUTING.rst
├── HISTORY.rst
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.rst
├── docs
│   ├── Makefile
│   ├── authors.rst
│   ├── conf.py
│   ├── contributing.rst
│   ├── history.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── make.bat
│   ├── readme.rst
│   └── usage.rst
├── python_workshop_example
│   ├── __init__.py
│   ├── cli.py
│   └── python_workshop_example.py
├── requirements_dev.txt
├── setup.cfg
├── setup.py
├── tests
│   ├── __init__.py
│   └── test_python_workshop_example.py
└── tox.ini

That’s quite a lot of files, but most of them you can safely ignore or delete - they are created mostly for your convenience. For example, you can list the authors of the package in the AUTHORS.rst file, write down what changed between each version in HISTORY.rst or explain how to use your project in README.rst.

But for us, just a few files are important right now:

  • Makefile - if you never used Makefiles and you think they are scary - give them a second chance! Makefiles are a great way to group together some shell commands that can make your life easier. You can define build command that will glue together various Docker build commands, clean command that will delete the __pycache__ files, or test that will run pytest with some predefined parameters, so you don’t have to remember them.
  • docs directory - this is where the documentation lives. I will talk more about using Sphinx to generate documentation later in this workshop, so let’s skip this folder for now.
  • python_workshop_example directory - this is where the code for our application is located. Inside we have three files:

    • __init__.py- simply creating this file marks this directory as a “python package”. There are some other benefits of using __init__.py files (like, controlling what from my_module import * actually imports), but usually you will leave it empty.
    • cli.py - because we selected Click as a command-line interface when answering cookiecutter questions, this file was created for us (and registered as an entry point). You can put some commands here, and they will be turned into CLI commands. For example, let’s say you write a foo command and publish your package on PyPI, then someone can install it with pip and run your command in the shell:
    $ python_workshop_example foo
    

    If you choose the “No command-line interface” option, this file won’t be here. * python_workshop_example.py - this is the main file of our module. You start writing code here. Once you have a lot of code, you will probably create more files and folders to separate it nicely.

  • requirements_dev.txt - this file contains a list of Python packages needed for development of your package. You will use them when developing your package (it has flake8 to lint your code, pytest to run tests, etc.). But those are not the packages that the end-user of your package will install! The “end-user” packages are listed in the setup.py file (in other projects you might see them in a file called requirements.txt).

  • setup.cfg contains settings for various tools that you will be using during development (for example, flake8 or pytest settings). You can safely ignore it for now.

  • setup.py - this is probably the most complicated file in our whole setup. It contains a bunch of settings to let you easily publish your package on PyPI, or install it with pip. The good news is - it’s already set up for you, so you don’t have to touch it!

With this boilerplate, you can already publish your package on PyPI or set up ReadTheDocs page. You can find more information on the cookiecutter-pypackage tutorial website.

Advantages of using cookiecutter

One interesting side-effect of using cookiecutters is that they will usually try to provide some additional tools that their authors think will help you in the development process. Stable and reliable tools that many other Python programmers are using, not a new, shiny toys published yesterday on “Show HackerNews”.

The cookiecutter-pypackage installed tox (to run your tests under different Python versions) and Sphinx (for documentation) - tools that you would probably want to use when writing a Python library.

Some templates will be more opinionated (and install more tools), some will be more “bare-bone”. In the end, it’s up to you to choose what you want to use in your project.

I suggest that you select a template that feels the most appropriate for your project (whether it’s a Flask or Django application or a Python module) and remove what you don’t need.