Cookiecutter - PyData Berlin 2017

Cookiecutter - PyData Berlin 2017

Cookiecutter is a command-line utility that generates projects from templates. You can use Cookiecutter to create new Python projects and to generate the initial code for different types of applications.

In this talk, I will give an introduction to Cookiecutter, how to install it
from PyPI, how to use the CLI and finally how to author your own template.

https://pydata.org/berlin2017/schedule/presentation/49/

F6e87b8993f94c06de18c85d1b3b7fb2?s=128

Raphael Pierzina

July 01, 2017
Tweet

Transcript

  1. 5.

    • Maintainer and core developer of Cookiecutter • Contributor to

    pytest and community person • Creator of the cookiecutter-pytest-plugin template • Software Engineer at moovel Group
  2. 7.

    Agenda 1. What is Cookiecutter? 2. How does Cookiecutter work?

    3. Create your own Cookiecutter template 4. Popular Cookiecutter templates 5. Demo: A custom Jupyter widget
  3. 12.

    full_name [Raphael Pierzina]: email [raphael@hackebrot.de]: github_username [hackebrot]: plugin_name [foobar]: emoji

    module_name [emoji]: short_description [A simple plugin to use with Pytest]: emoji plugin version [0.1.0]: pytest_version [3.1.1]: 3.1.2 Select docs_tool: 1 - mkdocs 2 - sphinx 3 - none Choose from 1, 2, 3 [1]: 1 Select license: 1 - MIT 2 - BSD-3 3 - GNU GPL v3.0 4 - Apache Software License 2.0 5 - Mozilla Public License 2.0 Choose from 1, 2, 3, 4, 5 [1]: 2 INFO:post_gen_project:Moving files for mkdocs. INFO:post_gen_project:Removing all temporary license files INFO:post_gen_project:Removing jinja2 macros py @hackebrot
  4. 13.

    pytest-emoji/ ├── LICENSE ├── MANIFEST.in ├── README.rst ├── appveyor.yml ├──

    docs │ └── index.md ├── mkdocs.yml ├── pytest_emoji.py ├── setup.py ├── tests │ ├── conftest.py │ └── test_emoji.py └── tox.ini py @hackebrot
  5. 15.

    Features • Cross-platform: Windows, Mac, and Linux are officially supported

    • Works with CPython 2.7, 3.3, 3.4, 3.5, 3.6 and PyPy • Project templates can be in any programming language or markup format @hackebrot
  6. 20.

    Community • Free and open source software: BSD license •

    154 individual contributors from around the world • More than 1000 public templates on GitHub @hackebrot
  7. 21.

    Contributing • Development of Cookiecutter is community-driven • Connect with

    other Cookiecutter contributors and users on https://gitter.im/audreyr/cookiecutter • Everyone is invited to contribute! @hackebrot
  8. 23.

    CLI + Python API • Cookiecutter can be either used

    as a command- line interface app or as a Python library • Both interfaces support a number of options for controlling the level of verbosity, suppressing user prompting, providing extra context and many other things @hackebrot
  9. 26.

    # -*- coding: utf-8 -*- from cookiecutter.main import cookiecutter def

    run_cookiecutter(): template = 'gh:pytest-dev/cookiecutter-pytest-plugin' project_dir = cookiecutter(template) print(f"Project generated in {project_dir}!") if __name__ == '__main__': run_cookiecutter() py @hackebrot
  10. 27.

    Templating with Jinja2 • Jinja2 is a modern and designer-friendly

    templating language for Python, modelled after Django’s templates. • It is fast, widely used and secure with the optional sandboxed template execution environment @hackebrot
  11. 28.

    # -*- coding: utf-8 -*- import pytest def pytest_addoption(parser): group

    = parser.getgroup('{{cookiecutter.plugin_name}}') group.addoption( ' --foo', action='store', dest='dest_foo', default='{% now "utc", "%Y" %}', help='Set the value for the fixture "bar".' ) parser.addini('HELLO', 'Dummy pytest.ini setting') py @hackebrot
  12. 29.

    { "full_name": "Raphael Pierzina", "github_username": "hackebrot", "plugin_name": "foobar", "module_name": "{{

    cookiecutter.plugin_name|lower|replace('-', '_') }}", "short_description": "A simple plugin to use with Pytest", "version": "0.1.0", "pytest_version": "3.1.1", "docs_tool": ["mkdocs", "sphinx", "none"], "license": [ "MIT", "BSD-3", "GNU GPL v3.0", "Apache Software License 2.0", "Mozilla Public License 2.0" ] } json @hackebrot
  13. 30.

    git + mercurial (+ zip) • Cookiecutter works with local

    templates on your filesystem or remote Git or Mercurial repositories • Short-hands for GitHub, BitBucket, and GitLab • Open Pull Request for adding support for templates from zip files or zip URLs (#961) @hackebrot
  14. 32.

    Template project • Cookiecutter takes a source directory tree and

    copies it into your new project • It replaces all the names that it finds surrounded by templating tags {{ and }} with names that it finds in the cookiecutter.json file @hackebrot
  15. 34.

    Cookiecutter namespace • Anything inside templating tags can be placed

    inside a namespace. • cookiecutter.project_slug will be looked up as project_slug in cookiecutter.json @hackebrot
  16. 36.
  17. 37.

    Context • Cookiecutter needs a context file to look up

    all your templates items • This file goes into our hello-pydata directory, and contains all the names we’ve used @hackebrot
  18. 45.
  19. 46.

    Jinja2 syntax • {% … %} for statements • {{

    … }} for expressions to print the template output • {# … #} for comments not included in the template output @hackebrot
  20. 47.

    Jinja2 control structures • For: Loop over each item in

    a sequence • If: Test if a variable is defined or if it’s equal to some other value • Macros: Useful to put often used idioms into reusable functions @hackebrot
  21. 49.

    Jinja2 control structures • Assignments: Assign values to variables •

    Include: Return a rendered template into the current namespace • … @hackebrot
  22. 50.

    {%- if cookiecutter.license == "MIT" -%} {%- include 'licenses/MIT' %}

    {%- elif cookiecutter.license == "BSD-3" -%} {%- include 'licenses/BSD-3' %} {%- elif cookiecutter.license == "GNU GPL v3.0" -%} {%- include 'licenses/GPL-3' %} {%- elif cookiecutter.license == "Apache Software License 2.0" -%} {%- include 'licenses/Apache-2' %} {%- elif cookiecutter.license == "Mozilla Public License 2.0" -%} {%- include 'licenses/MPL-2' %} {%- endif -%} txt @hackebrot
  23. 51.

    Jinja2 filters • replace: Return a copy of the value

    with all occurrences of a substring replaced • lower: Convert a value to lowercase • upper: Convert a value to uppercase @hackebrot
  24. 52.

    { "full_name": "Raphael Pierzina", "github_username": "hackebrot", "plugin_name": "foobar", "module_name": "{{

    cookiecutter.plugin_name|lower|replace('-', '_') }}", "short_description": "A simple plugin to use with Pytest", "version": "0.1.0", "pytest_version": "3.1.1", "docs_tool": ["mkdocs", "sphinx", "none"], "license": [ "MIT", "BSD-3", "GNU GPL v3.0", "Apache Software License 2.0", "Mozilla Public License 2.0" ] } json @hackebrot
  25. 53.

    Jinja2 filters • tojson: Dump a structure to a JSON

    string • sort: Sort an iterable in ascending order by default, or descending with an extra arg. Also allows to sort by an attribute @hackebrot
  26. 54.

    Jinja2 filters • select: Filter a sequence of objects by

    applying a test to each object • groupby: Group a sequence of objects by a common attribute @hackebrot
  27. 55.

    Jinja2 extensions • jinja2-time: Builtin into cookiecutter to insert a

    string representation of a datetime object • … • … @hackebrot
  28. 56.

    {#- source: http: //opensource.org/licenses/MIT #} The MIT License (MIT) Copyright

    (c) {% now 'utc', '%Y' %} {{cookiecutter.full_name}} Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. txt @hackebrot
  29. 59.

    cookiecutter-pypackage • Project structure for Python packages • Testing with

    unittest or pytest • Tox for testing compatibility across Python versions • Sphinx for documentation @hackebrot
  30. 61.

    cookiecutter-django • Template for Django 1.10 and Python 3.4 or

    3.5 • Optimized development and production settings • tests with unittest or pytest and 100% test coverage • Docker support using docker-compose • Bootstrap, 12-Factor, SSL, many other features @hackebrot
  31. 63.

    cookiecutter-pytest-plugin • Installable PyPI package with comprehensive README.rst file •

    Tests for your plugin with tox, pytest, and CI config • Example code for a fixture, a CLI option, and a pytest.ini option • Optional documentation with either Sphinx or MkDocs • Choose from several FOSS licenses @hackebrot
  32. 65.

    Python-iOS-template • Generates Python apps that will run under iOS

    • Supports Python 2.7, 3.4, and 3.5 • Works well with the toga GUI toolkit for native iOS widgets @hackebrot
  33. 68.
  34. 69.

    If you or your company are using Cookiecutter, please support

    its development! patreon.com/hackebrot @hackebrot