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”.
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.
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 [firstname.lastname@example.org]: email@example.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 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
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
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
buildcommand that will glue together various Docker build commands,
cleancommand that will delete the __pycache__ files, or
testthat will run pytest with some predefined parameters, so you don’t have to remember them.
docsdirectory - 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
foocommand 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
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.
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”.
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.