DEV Community

Chaps
Chaps

Posted on

Creating a python package with cookiecutter

When working with python as your programming language you usually will want to provide your code to others (or to yourself) so end users can make use of it or integrate it as part of a general project, implementation or solution.

The most common way to achieve this is to provide your code as a python package so that anyone can leverage and use it with a simple import statement
e.g.

import my_python_package
Enter fullscreen mode Exit fullscreen mode

by doing this anyone (with access to the package), will not only be able to use it but also to extend it if they need a particular implementation based on your solution.

An easy way to create a python package is by using the cookiecutter tool, cookiecutter is a python package itself that allows us to create boilerplates dynamically, avoiding having to copy/clone the base source and editing it, cookiecutter templates can be written in a way that they end up requesting input from the user in order to set different variables used across the template.

By following this guide we will create an example python package

  1. Create a virtual environment with your desired interpreter:
python3 -m venv virtcookiecutter
Enter fullscreen mode Exit fullscreen mode
  • This will leave a directory named “virtcookiecutter” under the CurrentWorkingDirectory where the previous command was executed.

    • Activate your virtual environment:
source virtcookiecutter/bin/activate
Enter fullscreen mode Exit fullscreen mode

I got into an issue where while running the next step, the pip installation process raised a not recognized command which comes from a missing dependency:

error: invalid command 'bdist_wheel' 
Enter fullscreen mode Exit fullscreen mode

So we will install the dependency (wheel) for the bdist_wheel command to exist:

pip install wheel
Enter fullscreen mode Exit fullscreen mode
  • Next, we will need to install cookiecutter in our (now activated) virtual environment
pip install cookiecutter
Enter fullscreen mode Exit fullscreen mode
  • And let’s use cookiecutter with the cookiecutter template for a python package as it's argument:
cookiecutter https://github.com/audreyr/cookiecutter-pypackage.git
Enter fullscreen mode Exit fullscreen mode

The cookiecutter template creation will prompt some questions in order to set some variables used across the process:

You can basically search where are any of the requested variables being used in the template source code by getting the template sources

e.g.

git clone https://github.com/audreyr/cookiecutter-pypackage.git 
Enter fullscreen mode Exit fullscreen mode



) and recursively searching for the variable name (they will be referenced across the template like this

e.g. *cookiecutter.variable_name *

Example prompt and inputs:

full_name [Audrey Roy Greenfeld]: Ernesto Solis Diaz
email [audreyr@example.com]: example@domain.org
github_username [audreyr]: chaps
project_name [Python Boilerplate]: Python Cookiecutter Example
project_slug [python_cookiecutter_example]:      
project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]: An initial example of using cookiecutter
pypi_username [chaps]: 
version [0.1.0]: 
use_pytest [n]: 
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]: 2
create_author_file [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]: 
Enter fullscreen mode Exit fullscreen mode

This will end up creating a directory with the name of the project_slug, inside this directory, you’ll find the contents of the boilerplate with the values you used during the prompt process:

ls python_cookiecutter_example/
AUTHORS.rst  CONTRIBUTING.rst  docs  HISTORY.rst  LICENSE  Makefile  MANIFEST.in  python_cookiecutter_example  README.rst  requirements_dev.txt  setup.cfg  setup.py  tests  tox.ini
Enter fullscreen mode Exit fullscreen mode

Now you can install your created python package:

Change your current working directory into the created python package directory:

cd python_cookiecutter_example/
Enter fullscreen mode Exit fullscreen mode

And install your package with pip:

pip install .
Enter fullscreen mode Exit fullscreen mode

Output:

Processing /path/to/python_cookiecutter_example
Installing collected packages: python-cookiecutter-example
  Running setup.py install for python-cookiecutter-example ... done
Successfully installed python-cookiecutter-example-0.1.0
Enter fullscreen mode Exit fullscreen mode

List your current packages and see python-cookiecutter-example being installed:

 pip freeze
Enter fullscreen mode Exit fullscreen mode

Output: (notice python-cookiecutter-example==0.1.0 )

arrow==0.15.5
binaryornot==0.4.4
certifi==2019.11.28
chardet==3.0.4
Click==7.0
cookiecutter==1.7.0
future==0.18.2
idna==2.8
Jinja2==2.10.3
jinja2-time==0.2.0
MarkupSafe==1.1.1
pkg-resources==0.0.0
poyo==0.5.0
python-cookiecutter-example==0.1.0
python-dateutil==2.8.1
requests==2.22.0
six==1.13.0
urllib3==1.25.7
whichcraft==0.6.1
Enter fullscreen mode Exit fullscreen mode

Open a python REPL and examine some of the package created information:

Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

\>>> import python_cookiecutter_example
\>>> dir(python_cookiecutter_example)
['__author__', '__builtins__', '__cached__', '__doc__', '__email__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__']
\>>> python_cookiecutter_example.__author__
'Ernesto Solis Diaz'
You can add your package sources under the project_slug directory in order to add contents to your package and be able to import them. 
Enter fullscreen mode Exit fullscreen mode

References:

Feel free to leave any comment on feedback :)

Top comments (1)

Collapse
 
miniscruff profile image
miniscruff

For global packages in python I recommend using pipx, it will create a venv for you and add it to the PATH. eg: pip install pipx; pipx install cookiecutter. Or if you are on Unix, pyenv can do similar stuff I believe.

Great post tho, I have looked 5 cookie cutters at work for everything from a python service to docker images.