Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ permissions:
contents: read

jobs:
tests:
name: tests
pytest:
name: Run tests
runs-on: ubuntu-latest

steps:
Expand Down
41 changes: 17 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,28 @@
![Nix Flakes](https://img.shields.io/badge/Nix-Flakes-blue?logo=nixos&logoColor=white)
![uv](https://img.shields.io/badge/Package_Manager-uv-blue)
[![Tests](https://img.shields.io/badge/CI-Tests-green?logo=github&logoColor=white)](https://github.com/haztecaso/python-template/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

</div>

A modern cookiecutter template for Python projects using `uv` as the package manager, Nix flakes for reproducibility, and a clean development setup.

## 🚀 Usage

### Creating a new project

If you want to keep your project in sync with this template, you can use
*cruft*.

```bash
cruft create gh:haztecaso/python-template
```

Otherwise you can stick with *cookiecutter*.

```bash
cookiecutter gh:haztecaso/python-template
```

## Features

### Current Features
Expand Down Expand Up @@ -42,26 +58,3 @@ A modern cookiecutter template for Python projects using `uv` as the package man
- 🔄 **Enhanced CI**: GitHub Action test matrix for multi-environment testing
- 🐍 **PyPy**: Registry setup and GitHub Action for multi-interpreter testing

## 🚀 Usage

This template requires the [Nix package manager](https://nixos.org/). You can install `cookiecutter` in your preferred way or create a temporal shell with it:

```bash
nix-shell -p cookiecutter
```

### Creating a new project

```bash
cookiecutter gh:haztecaso/python-template
```

### Initial setup

```bash
# If you use direnv
direnv allow

# manually activate the development environment
nix develop
```
2 changes: 1 addition & 1 deletion hooks/post_gen_project.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ uv sync --dev
uv run black src tests
uv run isort src tests
nix build
git init && git branch -m "main" && git add .
git init --initial-branch=main && git add .
uv run pre-commit install --hook-type commit-msg --hook-type pre-commit
8 changes: 7 additions & 1 deletion tests/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ def test_pytest_runs(project: Result):
test_dir = project_path / "tests"
assert test_dir.is_dir(), f"Expected tests directory not found: {test_dir}"

# Sync test dependencies
process = run_command("uv sync --group test", project_path)
assert (
process.returncode == 0
), f"uv sync failed with error: {process.stderr}\nOutput: {process.stdout}"

process = run_command("uv run pytest -xvs", project_path)

assert (
Expand Down Expand Up @@ -151,7 +157,7 @@ def test_mkdocs_runs(project: Result):

assert (
process.returncode == 0
), f"pytest failed with error: {process.stderr}\nOutput: {process.stdout}"
), f"mkdocs failed with error: {process.stderr}\nOutput: {process.stdout}"
assert (
"Documentation built in" in process.stderr
), f"Expected 'Documentation built in' in mkdocs build stderr, but got: {process.stderr}"
Expand Down
8 changes: 3 additions & 5 deletions {{cookiecutter.project_slug}}/.github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
name: docs
name: Docs

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
# Allow manual trigger
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
build:
name: Mkdocs build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -47,6 +44,7 @@ jobs:
path: ./site

deploy:
name: Deploy to github pages
environment:
name: github-pages
url: {% raw -%}${{ github.event.repository.html_url }}/{%- endraw %}
Expand Down
6 changes: 3 additions & 3 deletions {{cookiecutter.project_slug}}/.github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: test
name: Test

on:
push:
Expand All @@ -10,8 +10,8 @@ permissions:
contents: read

jobs:
uv-example:
name: python
pytest:
name: Run tests
runs-on: ubuntu-latest

steps:
Expand Down
12 changes: 10 additions & 2 deletions {{cookiecutter.project_slug}}/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# {{ cookiecutter.project_name }}

{{ cookiecutter.project_short_description }}
<div align="center">
*{{ cookiecutter.project_short_description }}*
</div>

<div align="center">
![Test](https://github.com/{{cookiecutter.github_username}}/{{cookiecutter.project_slug}}/actions/workflows/test.yml/badge.svg)
</div>

---

{% if cookiecutter.use_mkdocs == 'y' %}
[docs](https://{{cookiecutter.github_username}}.github.io/{{cookiecutter.project_slug}})
[**Documentation**](https://{{cookiecutter.github_username}}.github.io/{{cookiecutter.project_slug}})
{%- endif %}
24 changes: 1 addition & 23 deletions {{cookiecutter.project_slug}}/docs/index.md
Original file line number Diff line number Diff line change
@@ -1,23 +1 @@
{{ cookiecutter.project_short_description }}

## Installation

```bash
pip install {{ cookiecutter.project_slug }}
```

## Usage

```python
from {{ cookiecutter.project_slug }} import example

# Add usage examples here
```

## Features

* Add your project features here

## License

{{ cookiecutter.open_source_license }}
{! include_markdown "../README.md" start="<!--start-->" !}
20 changes: 10 additions & 10 deletions {{cookiecutter.project_slug}}/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ markdown_extensions:
- abbr
- def_list
- admonition
# We need the markdown-include to inject files into other files
- markdown_include.include:
base_path: docs
- meta
- toc:
permalink: true
Expand Down Expand Up @@ -65,20 +62,23 @@ markdown_extensions:
- pymdownx.tilde

plugins:
- search
- autolinks
- include-markdown:
opening_tag: "{!"
closing_tag: "!}"
- git-revision-date-localized:
type: timeago
fallback_to_build_date: true
- minify:
minify_html: true
- mkdocstrings:
handlers:
python:
options:
show_source: true
show_submodules: true
docstring_style: google
- autolinks
- git-revision-date-localized:
type: timeago
fallback_to_build_date: true
- minify:
minify_html: true
- search
- section-index

nav:
Expand Down
3 changes: 3 additions & 0 deletions {{cookiecutter.project_slug}}/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ dev = [
"isort",
"pre-commit",
"pyright",
]
test = [
"pytest",
{%- if cookiecutter.use_asyncio.lower() == "y" %}
"pytest-asyncio",
Expand All @@ -41,6 +43,7 @@ docs = [
"mkdocs-autolinks-plugin",
"mkdocs-git-revision-date-localized-plugin",
"mkdocs-htmlproofer-plugin",
"mkdocs-include-markdown-plugin",
"mkdocs-material",
"mkdocs-minify-plugin",
"mkdocs-section-index",
Expand Down