Cookiecutter
Cookiecutter is a command-line utility that creates projects from project templates. It streamlines the setup of new projects, such as Python packages, web applications, or data science projects, by prompting the user for configuration details and rendering files based on Jinja2 templates. Currently at version 2.7.1, it maintains an active release cadence with frequent updates and community contributions, supporting Python 3.10 and newer.
Warnings
- breaking Python 3.9 and older versions are no longer officially supported. `cookiecutter` now requires Python 3.10 or newer for versions 2.7.0 and later.
- gotcha In version 2.7.0, the `cookiecutter -V` command incorrectly reported the version as 2.6.0, despite the installed package being 2.7.0. The programmatic `cookiecutter.__version__` was correct.
- gotcha Cookiecutter templates can execute arbitrary code through hook scripts (e.g., `pre_gen_project.py`). Users should only use templates from trusted sources, as malicious templates can compromise your system.
- gotcha When using `jinja2_time` in templates, ensure a timezone is explicitly set (e.g., in `cookiecutter.json` or environment variables) to avoid unexpected date/time behavior, as `jinja2_time` does not provide a default timezone.
Install
-
pip install cookiecutter
Imports
- cookiecutter
from cookiecutter.main import cookiecutter
Quickstart
from cookiecutter.main import cookiecutter
import os
import shutil
# Define a temporary output directory
output_dir = './my_new_project_temp'
# Define a simple local template for demonstration
template_path = './my_template'
# Create a simple template for demonstration purposes
# In a real scenario, you'd clone from a Git URL or use a local template.
if not os.path.exists(template_path):
os.makedirs(os.path.join(template_path, '{{ cookiecutter.repo_name }}'))
with open(os.path.join(template_path, 'cookiecutter.json'), 'w') as f:
f.write('{"repo_name": "my-project"}')
with open(os.path.join(template_path, '{{ cookiecutter.repo_name }}', 'README.md'), 'w') as f:
f.write('Hello, {{ cookiecutter.repo_name }}!')
print(f"Generating project from template: {template_path}")
# Run cookiecutter programmatically
# This will prompt for 'repo_name' unless `no_input=True` is used
# or default_context is provided.
# For a runnable quickstart, we'll provide default_context and no_input.
try:
cookiecutter(
template_path,
no_input=True, # Set to False to be prompted
extra_context={'repo_name': 'my-generated-project'},
output_dir=output_dir,
overwrite_if_exists=True
)
print(f"Project successfully generated in {os.path.join(output_dir, 'my-generated-project')}")
# Verify a file exists
generated_file = os.path.join(output_dir, 'my-generated-project', 'README.md')
if os.path.exists(generated_file):
with open(generated_file, 'r') as f:
print(f"Content of {generated_file}:\n{f.read()}")
else:
print("Error: Generated file not found.")
except Exception as e:
print(f"An error occurred: {e}")
finally:
# Clean up the temporary template and generated project
if os.path.exists(template_path):
shutil.rmtree(template_path)
if os.path.exists(output_dir):
shutil.rmtree(output_dir)
print("Cleanup complete.")