Jumpstart your projects with cookiecutter

Humphrey Butau

@hamub

Have you ever desired a tool that can automate all the boring tasks you repeat when starting a python project?

Do you want to break free from cargo cult programming?

“ Cargo cult programming is a style of computer programming characterized by the ritual inclusion of code or program structures that serve no real purpose. ”

Cookiecutter!

What does cookiecutter do?

  • It takes a cookiecutter compliant template and rolls a project for you

  • It does that by asking a set of questions specified in your template

Features?

Cookiecutter runs on Mac, Windows and Linux

Easy to work with from the command line

Templates can be any language

Every file type is templatable (using Jinja2)

You can add hooks to automate project creation further more

Directory names and filenames can be templated

supports unlimited level of directort nesting

Getting started with cookiecutter

You can start by installing it in your virtual environment

                                  pip install cookiecuttter
                                  
or on Debian systems you could:

                                  sudo apt-get install cookiecutter
                                  
or for Mac:

                                   brew install cookiecutter
                                  
you can start with templates on github like so:

                                    $ cookiecutter https://github.com/audreyr/cookiecutter-pypackage
                                    
or by using shortcuts:

                                    $ cookiecutter gh:audreyr/cookiecutter-pypackage
                                    
you can also specify local cookiecutter templates

                                            $ cookiecutter ~/.cookiecutters/cookiecutter-pypackage/
                                            $ cookicutter cookiecutter-pypackage
                                            
Or call it from within python

                                          (pycon) ~  $ python
                                          Python 3.5.2 (default, Nov 17 2016, 17:05:23)
                                          [GCC 5.4.0 20160609] on linux
                                          Type "help", "copyright", "credits" or "license" for more information.

                                          >>> from cookiecutter.main import cookiecutter
                                          >>> cookiecutter("cookiecutter-pypackage")
                                          

jumpstarting a project with cookiecutter


                                                  (pyladies) ~/dev/pyconza (master) $ cookiecutter cookiecutter-pypackage
                                                  full_name [Audrey Roy Greenfeld]: Example User
                                                  email [aroy@alum.mit.edu]: user@example.com
                                                  github_username [audreyr]: user
                                                  project_name [Python Boilerplate]: pyconza_project
                                                  project_slug [pyconza_project]:
                                                  project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]: A pyconza project to demonstrate how awesome cookiecutter is
                                                  pypi_username [user]:
                                                  version [0.1.0]:
                                                  use_pytest [n]: y
                                                  use_pypi_deployment_with_travis [y]: y
                                                  Select command_line_interface:
                                                  1 - Click
                                                  2 - No command-line interface
                                                  Choose from 1, 2 [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]: 1
                                                  (pyladies) ~/dev/pyconza (master) $ cd pyconza_project/
                                                

                                                    (pyladies) ~/dev/pyconza/pyconza_project (master) $ ls
                                                    AUTHORS.rst       docs         LICENSE   MANIFEST.in      README.rst            setup.cfg  tests    travis_pypi_setup.py
                                                    CONTRIBUTING.rst  HISTORY.rst  Makefile  pyconza_project  requirements_dev.txt  setup.py   tox.ini
                                                  (pyladies) ~/dev/pyconza/pyconza_project (master) $ tree
                                                 

Inside a cookiecutter template


                                              |
                                              |
                                              _____cookiecutter.json
                                              |
                                              |
                                              _____{{cookiecutter.project_name}} # this folder contains the metadata
                                                  |
                                                  |____file.txt #this file will not be templated
                                                
cookiecutter.json

                                              {
                                                  "project_name": "Project name",
                                                  "author": "Your Name",
                                                  "username": "{{ cookiecutter.author|lower() }}",
                                                  "email": "you@domain.com",
                                                  "create_superuser": "no",
                                                  "repo_name": "{{ cookiecutter.project_name|replace(' ', '_')|lower() }}",
                                                  "module_prefix": "{{ cookiecutter.repo_name|replace('_', '-') }}",
                                                  "python_executable": "python3.5",
                                                  "bootstrap_version": "3.3.7",
                                                  "fontawesome_version": "4.7.0"
                                              }
                                              
directory listing of a cookiecutter template

we can use jinja2 templates


				{% if cookiecutter.create_superuser == 'yes' %}
				  echo "Creating superuper {{ cookiecutter.username }}"
				  python manage.py createsuperuser --username {{ cookiecutter.username }} --email {{ cookiecutter.email }}
				{% endif %}v 
				  

"username": "{{ cookiecutter.author|lower()}}

"module_prefix": "{{cookiecutter.repo_name|replace('_', '-')}}

Escaping

{% raw %}{% extends "base.html" %}{% endraw %}

Advanced uses of cookiecutter

Hooks

cat hooks/post_gen_project.sh


                                  #!/bin/bash
                                  USER="{{ cookiecutter.username }}"
                                  EMAIL="{{ cookiecutter.email }}"
                                  if [ `which virtualenv|grep virtualenv 2>/dev/null` ]
                                  then
                                  virtualenv -p {{ cookiecutter.python_executable }} venv
                                  else
                                  {{cookiecutter.python_executable}} -m venv venv
                                  fi
                                  source venv/bin/activate
                                  cd back
                                  echo "Installing backend dependencies"
                                  pip install --upgrade pip setuptools
                                  pip install -r requirements.txt
                                  pip freeze --local > requirements.txt
                                  cp environ.py.dist environ.py
                                  python manage.py migrate --noinput
                                  {% if cookiecutter.create_superuser == 'yes' %}
                                  echo "Creating superuper {{ cookiecutter.username }}"
                                  python manage.py createsuperuser --username {{ cookiecutter.username }} --email {{ cookiecutter.email }}
                                  {% endif %}
                                  deactivate
                                  
replay your cookiecutter

                                  cookiecutter --replay gh:audreyr/cookiecutter-pypackage
                                  
calling cookiecutter from python

                                  from cookiecutter.main import cookiecutter
                                  # Create project from the cookiecutter-pypackage/ template
                                  cookiecutter('cookiecutter-pypackage/')
                                  # Create project from the cookiecutter-pypackage.git repo template
                                  cookiecutter('https://github.com/audreyr/cookiecutter-pypackage.git')
                                  cookiecutter --replay gh:audreyr/cookiecutter-pypackage
                                  
Choice variables

                                {
                                  "postgresql_version": ["9.6", "9.5", "9.4", "9.3", "9.2"],
                                  "open_source_license": ["MIT", "BSD", "GPLv3", "Apache Software License 2.0", "Not open source"],
                                  "js_task_runner": ["Gulp", "Grunt", "None"]
                                }
                                  

My select cookiecutter templates

cookiecutter pypackage

Travis-CI: Ready for Travis Continuous Integration testing

 
                                    # Config file for automatic testing at travis-ci.org
                                        # This file will be regenerated if you run travis_pypi_setup.py

                                    language: python
                                    python:
                                      - 3.5
                                      - 3.4
                                      - 3.3
                                      - 2.7
                                      - 2.6

                                    # command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
                                    install: pip install -U tox-travis

                                    # command to run tests, e.g. python setup.py test
                                    script: tox

                                    {% if cookiecutter.use_pypi_deployment_with_travis == 'y' -%}
                                    # After you create the Github repo and add it to Travis, run the
                                    # travis_pypi_setup.py script to finish PyPI deployment setup
                                    deploy:
                                      provider: pypi
                                      distributions: sdist bdist_wheel
                                      user: {{ cookiecutter.pypi_username }}
                                      password:
                                        secure: PLEASE_REPLACE_ME
                                      on:
                                        tags: true
                                        repo: {{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}
                                        python: 2.7
                                    {%- endif %}
                                      
.travis.yml
Tox testing: Setup to easily test for Python 2.6, 2.7, 3.3, 3.4, 3.5

																	[tox]
																	envlist = py26, py27, py33, py34, py35, flake8

																	[travis]
																	python =
																			3.5: py35
																			3.4: py34
																			3.3: py33
																			2.7: py27
																			2.6: py26

																	[testenv:flake8]
																	basepython=python
																	deps=flake8
																	commands=flake8 {{ cookiecutter.project_slug }}

																	[testenv]
																	setenv =
																			PYTHONPATH = {toxinidir}
																	{% if cookiecutter.use_pytest == 'y' -%}
																	deps =
																			-r{toxinidir}/requirements_dev.txt
																	commands =
																			pip install -U pip
																			py.test --basetemp={envtmpdir}
																	{% else %}
																	commands = python setup.py test
																	{%- endif %}
																	
tox.ini

																	Get Started!
																	------------

																	Ready to contribute? Here's how to set up `{{ cookiecutter.project_slug }}` for local development.

																	1. Fork the `{{ cookiecutter.project_slug }}` repo on GitHub.
																	2. Clone your fork locally::

																			$ git clone git@github.com:your_name_here/{{ cookiecutter.project_slug }}.git

																			3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development::

																					$ mkvirtualenv {{ cookiecutter.project_slug }}
																							$ cd {{ cookiecutter.project_slug }}/
																									$ python setup.py developk
																	
CONTRIBUTING.rst
Levit's Django CookieCutter template for Django + Ember apps

  • Django
  • Django Rest Framework
  • Django Filter
  • Django CORS headers
  • Celery
  • Django Debug Toolbar and Django Debug Panel
  • Factory Boy
  • Ember
  • ember-django-adapter
  • ember-simple-auth

These dont match your requirements?

There is a pantry full of cookiecutter templates here:

https://github.com/audreyr/cookiecutter

Demo!
Creating the template directory

                               mkdir template
                               

                                  touch template/cookiecutter.json
                                  

                                  {
                                    "repo_name": "repo name",
                                    "email": "your email",
                                    "full_name": "yourname",
                                    "description": "what is this project about"
                                  }

                                  

                                  mkdir template/{{cookiecutter.repo_name}}
                                  

Questions?

Thanks for listening!

hbutau35@gmail.com

@hamub