Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c932d0c
remove and update CI workflows for template repo
Sahil590 May 20, 2026
3a19f93
update readme in template and repo
Sahil590 May 20, 2026
c56ecf3
update ci for template
Sahil590 May 20, 2026
77cf1b7
update cookiecutter json
Sahil590 May 20, 2026
2305cd9
use uv in the template repo
Sahil590 May 20, 2026
067a323
remove the requirements files as no longer needed
Sahil590 May 20, 2026
73b9a5c
remove refs to old tools and add a new hook for running uv add instea…
Sahil590 May 20, 2026
76ac340
remove the setuptools-scm versiona and initialise git instead
Sahil590 May 20, 2026
8c2c411
update ci pytest to use uv
Sahil590 May 20, 2026
e0460cc
update ci pytest to use uv
Sahil590 May 20, 2026
5bca66a
Change test command from 'uv pytest' to 'uv run -m pytest'
Sahil590 May 20, 2026
b74fb25
fix cookiecutter ci
Sahil590 May 20, 2026
ee22dac
Potential fix for pull request finding
Sahil590 May 20, 2026
bd2e1ed
update readme to add installtion of uv step
Sahil590 May 20, 2026
cb6238f
add check to see if uv is installed
Sahil590 May 20, 2026
0a792bc
Apply suggestions from code review
Sahil590 May 29, 2026
faf0d61
fix tests
Sahil590 Jun 8, 2026
c12579b
remove package option in cookiecutter
Sahil590 Jun 8, 2026
39d4b0f
update readme instructions to use uvx
Sahil590 Jun 8, 2026
a250542
mrege readme
Sahil590 Jun 8, 2026
837ab24
update package option in dependabot file
Sahil590 Jun 8, 2026
3c64ad7
update spelling
Sahil590 Jun 8, 2026
7bb33c2
Merge branch 'main' into update-uv
Sahil590 Jun 8, 2026
dac45b3
Fix markdownlint MD046 code block style and use subprocess.DEVNULL in…
Copilot Aug 7, 2026
51fd4aa
Merge remote-tracking branch 'origin/main' into update-uv
Sahil590 Aug 7, 2026
0546334
fix pre-commit
Sahil590 Aug 7, 2026
0eb9e32
undo copilot change
Sahil590 Aug 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 0 additions & 67 deletions .github/workflows/ci-pip-tools.yml

This file was deleted.

64 changes: 0 additions & 64 deletions .github/workflows/ci-poetry.yml

This file was deleted.

6 changes: 3 additions & 3 deletions .github/workflows/ci-uv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ jobs:
cache: pip

- name: Install dependencies
run: pip install -r dev-requirements.txt
run: uv sync

- name: Run unit tests
run: pytest
run: uv run pytest

- name: Create project from template
# Choose default options
run: cookiecutter . --no-input packaging=uv rse_team_as_coauthor=true use_bsd3_license=true
run: uv run cookiecutter . --no-input packaging=uv rse_team_as_coauthor=true use_bsd3_license=true

- name: Install project dependencies
working-directory: my_project
Expand Down
17 changes: 5 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<!-- markdownlint-disable MD041 -->
[![poetry](https://github.com/ImperialCollegeLondon/python-template/actions/workflows/ci-poetry.yml/badge.svg)](https://github.com/ImperialCollegeLondon/python-template/actions/workflows/ci-poetry.yml)
[![pip-tools](https://github.com/ImperialCollegeLondon/python-template/actions/workflows/ci-pip-tools.yml/badge.svg)](https://github.com/ImperialCollegeLondon/python-template/actions/workflows/ci-pip-tools.yml)

[![uv](https://github.com/ImperialCollegeLondon/python-template/actions/workflows/ci-uv.yml/badge.svg)](https://github.com/ImperialCollegeLondon/python-template/actions/workflows/ci-uv.yml)

# Python project template
Expand All @@ -9,8 +8,7 @@ This repo contains a [`cookiecutter`] template for a Python project, including
[`pre-commit`] hooks for linting and GitHub Actions for automatically running tests
using [`pytest`].

The template supports three Python packaging tools: [`poetry`], [`pip-tools`]
and [`uv`].
The template supports the Python packaging tool [`uv`].

It is particularly geared towards the needs of Imperial College's [Research Software
Engineering team], but hopefully it should be generically useful. If you find any
Expand All @@ -19,8 +17,6 @@ problems or have any questions, please [raise an issue].
[`cookiecutter`]: https://cookiecutter.readthedocs.io/en/stable/
[`pre-commit`]: https://pre-commit.com/
[`pytest`]: https://pytest.org/
[`poetry`]: https://python-poetry.org/
[`pip-tools`]: https://github.com/jazzband/pip-tools
[`uv`]: https://docs.astral.sh/uv/
[Research Software Engineering team]: https://www.imperial.ac.uk/admin-services/ict/self-service/research-support/rcs/service-offering/research-software-engineering/
[raise an issue]: https://github.com/ImperialCollegeLondon/python-template/issues/new
Expand All @@ -29,15 +25,12 @@ problems or have any questions, please [raise an issue].

To use this template for your own application:

1. [Install `cookiecutter`] following the instructions for your OS.
2. Create your own project using this template: `cookiecutter
gh:ImperialCollegeLondon/python-template`
1. [Install `uv`] following the instructions for your OS.
2. Create your own project using this template: `uvx cookiecutter
gh:ImperialCollegeLondon/python-template`
3. Choose the options you want for your project
4. To get started, follow the instructions in the readme of the newly created project

[Install `cookiecutter`]:
https://cookiecutter.readthedocs.io/en/stable/README.html#installation

# Extra setup

## Auto-merging bot PRs
Expand Down
5 changes: 0 additions & 5 deletions cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@
"author_email": "jane_doe@imperial.ac.uk",
"rse_team_as_coauthor": false,
"use_bsd3_license": false,
"packaging": [
"poetry",
"pip-tools",
"uv"
],
"mkdocs": true,
"add_precommit_workflows": true,
Comment thread
Sahil590 marked this conversation as resolved.
"automerge_bot_prs": false,
Comment thread
Sahil590 marked this conversation as resolved.
Expand Down
3 changes: 0 additions & 3 deletions dev-requirements.txt

This file was deleted.

99 changes: 38 additions & 61 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
@@ -1,85 +1,62 @@
import subprocess
import os
import re
from glob import glob
from shutil import rmtree

REMOVE_PATHS = (
"{% if not cookiecutter.use_bsd3_license %}LICENSE{% endif %}",
"{% if not cookiecutter.add_precommit_workflows %}.github/workflows/pre-commit*.yml{% endif %}",
"{% if not cookiecutter.automerge_bot_prs %}.github/workflows/auto-merge.yml{% endif %}",
"{% if cookiecutter.packaging != 'pip-tools' %}requirements.txt{% endif %}",
"{% if cookiecutter.packaging != 'pip-tools' %}dev-requirements.txt{% endif %}",
"{% if cookiecutter.packaging != 'pip-tools' or not cookiecutter.mkdocs %}doc-requirements.txt{% endif %}",
"{% if not cookiecutter.mkdocs %}docs{% endif %}",
"{% if not cookiecutter.mkdocs %}.github/workflows/docs.yml{% endif %}",
"README.*.jinja",
)

DEV_DEPS = (
"ruff",
"mypy",
"pre-commit",
"pytest",
"pytest-cov",
"pytest-mock",
)

def main():
# {% if cookiecutter.packaging == 'poetry' %}
update_poetry_dependencies()
# {% endif %}
# {% if cookiecutter.packaging == 'uv' %}
update_uv_dependencies()
# {% endif %}
remove_unneeded_files()

# mkdocs v2 will include breaking changes.
# See: https://github.com/ImperialCollegeLondon/python-template/discussions/530
DOC_DEPS = (
"mkdocs<2",
"mkdocstrings",
"mkdocstrings-python",
"mkdocs-material",
"mkdocs-gen-files",
"mkdocs-literate-nav",
"mkdocs-section-index",
)

def read_package_versions(*filenames: str) -> dict[str, str]:
"""Read package versions from *requirements.txt."""
regex = re.compile(r"^([^# ]+)==(.+)$")
packages: dict[str, str] = {}
for filename in filenames:
with open(filename) as f:
for line in f.readlines():
if match := regex.match(line):
name = match.group(1).lower()
version = match.group(2)
packages[name] = version
return packages
MKDOCS_ENABLED = "{{ cookiecutter.mkdocs }}" == "True"


def update_poetry_dependencies(pyproject_path: str = "pyproject.toml"):
"""Patch the versions of packages in pyproject.toml."""
packages = read_package_versions(
"doc-requirements.txt", "dev-requirements.txt", "requirements.txt"
)
def main():
check_uv_installed()
add_uv_dependencies()
remove_unneeded_files()

output = ""
regex = re.compile(r'^([^ ]+) = "VERSION"$')
with open(pyproject_path) as f:
for line in f.readlines():
if match := regex.match(line):
name = match.group(1)
output += f'{name} = "^{packages[name.lower()]}"\n'
else:
output += line
with open(pyproject_path, "w") as f:
f.write(output)

def check_uv_installed():
try:
subprocess.run(["uv", "--version"], check=True, stdout=subprocess.DEVNULL)
except FileNotFoundError:
print(
"Error: 'uv' command not found. Please install 'uv' to use this template."
)
exit(1)

def update_uv_dependencies(pyproject_path: str = "pyproject.toml"):
"""Patch the versions of packages in pyproject.toml."""
packages = read_package_versions(
"doc-requirements.txt", "dev-requirements.txt", "requirements.txt"
)

output = ""
regex = re.compile(r'"([A-Za-z0-9_\-]+)\s*([=<>!~]+)\s*VERSION\s*(.*)"')
with open(pyproject_path) as f:
for line in f.readlines():
if match := regex.match(line.strip()):
name = match.group(1)
operator = match.group(2)
version = packages[name.lower()]
trailing = match.group(3)
comma = "," if line.strip().endswith(",") else ""
output += f' "{name}{operator}{version}{trailing}"{comma}\n'
else:
output += line
with open(pyproject_path, "w") as f:
f.write(output)
def add_uv_dependencies():
subprocess.run(["git", "init"], check=True)
subprocess.run(["uv", "add", "--dev", *DEV_DEPS], check=True)
if MKDOCS_ENABLED:
subprocess.run(["uv", "add", "--group", "doc", *DOC_DEPS], check=True)
Comment thread
Sahil590 marked this conversation as resolved.
Comment thread
Sahil590 marked this conversation as resolved.
Comment thread
Sahil590 marked this conversation as resolved.
Comment thread
Sahil590 marked this conversation as resolved.


def remove_unneeded_files():
Expand Down
13 changes: 13 additions & 0 deletions pyproject.toml
Comment thread
Sahil590 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[project]
name = "python-template"
version = "0.1.0"
requires-python = ">=3.14"

[dependency-groups]
dev = [
"cookiecutter>=2.7.1",
"pytest>=9.0.3",
]

[tool.uv]
package = false
Loading