This is a Copier template for Python projects, allowing for template evolution over time and sharing across projects. It is strongly recommended you follow dev machine setup before following steps for generating a project from this template. In short, you should have Git, VSCode, Copier, Python, and the cross-platform PowerShell (with profile configurations to activate .env
variables), installed to get the most use out of this template.
This template should set up tooling that will help you as you code. Contributor and CI workflows in this template are tested on Windows 2022, MacOS 13, and Ubuntu 22.04 runners. Static analysis "moves errors to the left", allowing you to catch issues as soon as possible. Linting and code checks run as you write to catch problems before you run/publish/package your code. Features include:
pyright
: Code refactoring tools, allowing you to move/rename functions and variables around your project, effortlessly refactoring code as your project grows in complexity. Also performs type-checking which will keep you honest if you're using type annotations. But you don't have to use type annotations out of the gate, consier delaying that learning journey until you get the basics down.pytest
: Write tests for your code in tests
that ensure certain functionality works the way you say it does. The more robust your tests, the easier it is to make sweeping changes to your code.pre-commit
: Enforces the above standards at commit time. If you must, skip the check with git commit --no-verify
, but try to keep pre-commit
happy and you will be happier in the long run.ruff
: Formats code, enforces code style and best practices. Don't be afraid to suppress Ruff messages if you find them truly inappropriate for your use case, but consider the advice before suppressing messages.Projects generated from this template have some features that require certain GitHub apps to be set up. They are not strictly necessary, but bolster code style, Git operations, reproducibility and test coverage efforts:
pre-commit.ci
enabled to leverage automatic running of pre-commit
hooks online. This is not strictly necessary, but encouraged as a way to help keep your code in good shape as you write it.These requirements should only need to be installed once on a given machine. Until I unify the documentation, see this in-depth setup guide for details, including an Initialize-WindowsDev.ps1
script that magically does all of this for you on Windows (via winget
. Also, make sure you set up a GitHub account. Parts of this template assume you are hosting your project on GitHub. This template sets up GitHub Actions for you, a continuous integration (CI) tool that checks code for correctness, publishes documentation, and more.
py
, and facilitates multiple Python versions being installed.sudo apt install python3.11 python3.11-dev python3.11-venv python3.11-distutils python3.11-tk
. Make sure you at least install python#.##-venv
for your chosen Python..env
files to be loaded into the PowerShell session. This is necessary in this template for various tasks, since VSCode doesn't handle environment variables very well.code $PROFILE
in a pwsh
(PowerShell) terminal window. This opens your PowerShell profile in VSCode for editing. Modify it to contain the following:function Set-Env {
<#.SYNOPSIS
Load environment variables from `.env`, activate virtual environments.
#>
Set-PsEnv
$VENV_ACTIVATE_WINDOWS = '.venv/Scripts/activate'
$VENV_ACTIVATE_UNIX = '.venv/bin/Activate.ps1'
if ( Test-Path $VENV_ACTIVATE_WINDOWS ) { . $VENV_ACTIVATE_WINDOWS }
elseif ( Test-Path $VENV_ACTIVATE_UNIX ) { . $VENV_ACTIVATE_UNIX }
}
Set-Env
Generating a project from this template involves creating a local folder, initializing the project, and publishing the repository on GitHub.
example
.File: Open Folder
.git init
.copier copy gh:blakeNaccarato/copier-python .
and answer the questions..tools/scripts/Initialize_Repo.ps1
. You can inspect the setup script if you like. It does the following:
template
submodule for later updating.typings
submodule to synchronize pyright
in GitHub Actions with Pylance.The templated project is now published on GitHub. The project owner will have to set a few more options in the GitHub repository settings to enable documentation and GitHub Actions workflows to work.
Visit the newly-published GitHub repository, navigate to repository "Settings", and configure the following:
docs
, README.md
, and CHANGELOG.md
.sphinx.yml
action runs on detected changes to documentation files. Also manually enter a "Description" and other info here if you like.There is a lot still to do in this template, but the big one is the concept of "meta-templating". The saying that "one size fits all" doesn't hold in project templating. Rather, "many sizes fit most". I encourage you to fork this template and change the relevant links in your fork to take ownership of the template and modify it for your own needs.
I intend to set up a meta-templating solution over in copyit to automate this, facilitating the forking of templates from templates, to allow anyone to maintain their own template, periodically updating from whatever parent template they chose. This pattern allows individuals or teams to benefit from the templates of others, without being constrained by the opinionated choices of that template.
Other notable to-dos:
HEAD
of the template, but releases are known stable points and are better for forking.scripts/Sync-Py.ps1
)GITHUB_TOKEN
defaultsThis template uses Copier to do the heavy lifting. An alternative Copier template I came across recently is pawamoy/copier-uv, which also uses uv
like this template, and is slimmer in scope and approach. My template grew out of a need to ensure reproducibility for research code and facilitates "multi-repo" workflows, which is good for research code that incorporates lots of dependencies and acts as a "leaf" in the tree that is the Python ecosystem. To that end, my template features unique full-dependency-chain locking for every combination of operating system and Python version, a useful signal of research code reproducibility.
Pawamoy's template is a good choice for library development, where you are intentionally limiting your dependencies, and working on being a "branch" in the tree that is the Python ecosystem. There is no locking, but uv
compiles and installs dependencies all the same. See their copier-pdm also for some locking capabilities.
See this comparison of Copier to other project generators to get an idea as to why you would use a Copier-based template over something like Cookiecutter or Yeoman. See also, PyScaffold. In summary, Copier facilitates template evolution and periodic project updating from the template, rather than a one-time scaffold for your project. This encourages continual updating of the template to suit your project needs.
Blake Naccarato 💻 |