Copier

9.14.3 · active · verified Sat Apr 11

Copier is a versatile Python library and CLI tool designed for rendering project templates. It supports both local paths and Git URLs as template sources, allowing for dynamic replacement of values in various text files using Jinja2 templating. It handles project generation and updates, ensuring existing files are not overwritten unless explicitly instructed. The library is actively maintained with frequent updates, providing a robust solution for scaffolding and managing project lifecycles.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to programmatically use `copier.run_copy` to generate a new project from a local template. It first creates a minimal template directory with a `copier.yml` and a Jinja2-templated file, then copies it to a destination, providing answers as a dictionary. The generated project's README content is then printed.

import os
import shutil
from pathlib import Path
from copier import run_copy

# Define paths for demonstration
template_path = Path('./my_template')
dest_path = Path('./my_new_project')

# Clean up previous runs for idempotent quickstart
if dest_path.exists():
    shutil.rmtree(dest_path)
if template_path.exists():
    shutil.rmtree(template_path)

# 1. Create a dummy template structure
template_path.mkdir(exist_ok=True)
(template_path / 'copier.yml').write_text(
    """
    # questions
    project_name: 
      type: str
      help: What is your project name?
    author_name:
      type: str
      default: 'John Doe'
    """
)
(template_path / '{{ project_name }}').mkdir()
(template_path / '{{ project_name }}' / 'README.md.jinja').write_text(
    """
    # {{ project_name }}

    This project was generated by {{ author_name }}.
    """
)

print(f"Template created at: {template_path.resolve()}")

# 2. Programmatically copy the template
# In a real scenario, these answers might be interactively prompted or passed via CLI
answers = {
    'project_name': 'MyAwesomeProject',
    'author_name': 'AI Assistant'
}

run_copy(
    str(template_path),
    str(dest_path),
    data=answers,
    overwrite=True # Use with caution in real projects
)

print(f"Project generated at: {dest_path.resolve()}")
print("Generated README.md content:")
print((dest_path / 'MyAwesomeProject' / 'README.md').read_text())

# Clean up after quickstart
shutil.rmtree(template_path)
shutil.rmtree(dest_path)

view raw JSON →