Creating a python package with cookiecutter
Tags: python, cookiecutter
Published: 2020-01-20 21:20:07

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. 
```python
import my_python_package
```
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:

```bash
python3 -m venv virtcookiecutter
```

  - This will leave a directory named “virtcookiecutter” under the CurrentWorkingDirectory where the previous command was executed.


- Activate your virtual environment:

```bash
source virtcookiecutter/bin/activate
```
 

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: 

```bash
error: invalid command 'bdist_wheel' 
``` 

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

```bash 
pip install wheel
```

- Next, we will need to install cookiecutter in our (now activated) virtual environment

```bash
pip install cookiecutter
```

- And let’s use cookiecutter with the cookiecutter template for a python package as it's argument:

```bash
cookiecutter https://github.com/audreyr/cookiecutter-pypackage.git
```

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.** 
```bash
git clone https://github.com/audreyr/cookiecutter-pypackage.git 
``` ‑ 
 ) 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:

```bash
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]: 
```

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:

 
```bash
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
```


Now you can install your created python package:


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

```bash
cd python_cookiecutter_example/
```

And install your package with pip:
```
pip install .
```

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
```

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

 
```bash
 pip freeze
```

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
```

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. 
```


## References:

- https://cookiecutter.readthedocs.io/

- https://cookiecutter.readthedocs.io/en/1.7.0/installation.html

- https://cookiecutter.readthedocs.io/en/1.7.0/tutorial1.html#step-1-generate-a-python-package-project


Feel free to leave any comment on feedback :)