Skip to content

Commit e62328f

Browse files
committed
chore: Migrate dependency management from requirements/*.in to pyproject.toml
Complete migration from pip-tools workflow to modern uv-based dependency management: - Replace requirements/main.in, dev.in, production.in with pyproject.toml - Use PEP 735 dependency-groups for dev and production dependencies - Generate uv.lock as universal lock file (102 packages) - Auto-generate requirements.txt for Heroku compatibility - Centralize tool configurations (ruff, coverage, isort) in pyproject.toml - Use Hatchling as build backend - Update all tooling (Taskfile, toast.yml, Dockerfile, CI/CD) - Update documentation (CLAUDE.md, README.md, DEVELOPMENT.md, CONTRIBUTING.md) New workflow: - `uv lock` - Update lock file - `uv sync` - Install dependencies - `task dependencies:export` - Generate requirements.txt Benefits: - Single source of truth (pyproject.toml) - Faster dependency resolution with uv - Modern Python packaging standards (PEP 621, PEP 735) - Simplified dependency management commands Fixes #171
1 parent 17dd086 commit e62328f

File tree

19 files changed

+3357
-445
lines changed

19 files changed

+3357
-445
lines changed

.github/workflows/test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ jobs:
99
DJANGO_SETTINGS_MODULE: pythonie.settings.tests
1010
steps:
1111
- uses: actions/checkout@v2
12-
- name: Set Up Python 3.12
12+
- name: Set Up Python 3.13
1313
uses: actions/setup-python@v2
1414
with:
15-
python-version: "3.12"
15+
python-version: "3.13"
1616
- name: Install the dependencies
1717
run: |
18-
python -m pip install --upgrade pip setuptools uv
19-
python -m uv pip install -r requirements/main.txt -r requirements/dev.txt
18+
python -m pip install --upgrade pip uv
19+
uv sync
2020
- name: Run the tests
2121
run: |
2222
python pythonie/manage.py test pythonie --verbosity=2

CLAUDE.md

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Always specify settings module: `--settings=pythonie.settings.dev` (or `tests`,
5858
python3 -m venv pythonie-venv
5959
source pythonie-venv/bin/activate
6060
pip install uv
61-
uv pip install -r requirements.txt
61+
uv sync
6262

6363
# Database
6464
python pythonie/manage.py migrate --settings=pythonie.settings.dev
@@ -129,32 +129,66 @@ task code:check
129129

130130
### Dependency Management
131131

132-
Uses `uv` for fast Python package management. Dependencies are defined in `.in` files and compiled to `.txt` files:
132+
Uses `uv` with `pyproject.toml` for dependency management. Dependencies are defined in `pyproject.toml` and locked in `uv.lock`:
133133

134-
```bash
135-
# Recompile all dependencies
136-
task dependencies:compute
137-
# or: toast deps:compute
134+
**Structure:**
135+
- `pyproject.toml` - Dependency specifications (edit this to add/remove dependencies)
136+
- `uv.lock` - Locked versions (auto-generated, commit to git)
137+
- `requirements.txt` - Auto-generated for Heroku deployment
138138

139-
# Check outdated packages
140-
task dependencies:outdated
139+
**Common Commands:**
140+
141+
```bash
142+
# Update lock file after changing pyproject.toml
143+
task dependencies:lock
141144

142145
# Upgrade all dependencies
143146
task dependencies:upgrade
144147

145-
# Upgrade only Wagtail
146-
task dependencies:upgrade:wagtail
147-
148148
# Upgrade specific package
149149
task dependencies:upgrade:package PACKAGE=django
150150

151+
# Install dependencies (development)
152+
task dependencies:sync
153+
154+
# Install production dependencies only
155+
task dependencies:sync:production
156+
157+
# Generate requirements.txt for Heroku
158+
task dependencies:export
159+
160+
# Check outdated packages
161+
task dependencies:outdated
162+
151163
# Check for security vulnerabilities
152164
task dependencies:security
153165

154166
# Show dependencies tree
155167
task dependencies:tree
156168
```
157169

170+
**Adding a New Dependency:**
171+
172+
1. Edit `pyproject.toml` to add the dependency:
173+
```toml
174+
dependencies = [
175+
"new-package",
176+
# ...
177+
]
178+
```
179+
180+
2. Update lock and generate requirements.txt:
181+
```bash
182+
task dependencies:lock
183+
task dependencies:export
184+
```
185+
186+
3. Commit both files:
187+
```bash
188+
git add pyproject.toml uv.lock requirements.txt
189+
git commit -m "Add new-package dependency"
190+
```
191+
158192
### Database Operations (Heroku)
159193

160194
```bash

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ source pythonie-venv/bin/activate
8686

8787
# Install dependencies
8888
pip install uv
89-
uv pip install -r requirements/dev.txt
89+
uv sync
9090

9191
# Run migrations
9292
python pythonie/manage.py migrate --settings=pythonie.settings.dev

DEVELOPMENT.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ source pythonie-venv/bin/activate
169169

170170
# 2. Install dependencies
171171
pip install uv
172-
uv pip install -r requirements/dev.txt
172+
uv sync
173173

174174
# 3. Migrate database
175175
python pythonie/manage.py migrate --settings=pythonie.settings.dev
@@ -686,7 +686,7 @@ echo "django-debug-toolbar" >> requirements/main.in
686686
uv pip compile requirements/main.in -o requirements/main.txt
687687

688688
# Install
689-
uv pip install -r requirements/dev.txt
689+
uv sync
690690
```
691691

692692
### Database Migrations

Dockerfile

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,13 @@ RUN --mount=type=cache,target=/var/cache/apt \
55
apt install -y --no-install-recommends \
66
build-essential gcc neovim fish less iputils-ping postgresql-client \
77
ack
8-
ADD requirements/main.txt \
9-
requirements/dev.txt \
10-
requirements/production.txt \
11-
./requirements/
8+
9+
# Copy dependency specification files
10+
COPY pyproject.toml uv.lock ./
11+
1212
RUN --mount=type=cache,target=/root/.cache \
1313
pip install -U pip uv ruff && \
14-
python -m uv pip install \
15-
-r requirements/main.txt \
16-
-r requirements/dev.txt \
17-
-r requirements/production.txt aws
14+
uv sync --group production
1815

1916
FROM compile-stage AS tests-stage
2017

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ If you prefer to develop without Docker:
5656
3. Ensure you are running Python 3.13: `python -V` should output `Python 3.13.x`
5757
4. Create a virtualenv: `python3 -m venv pythonie-venv`
5858
5. Activate the virtualenv: `source pythonie-venv/bin/activate`
59-
6. Install uv and dependencies: `pip install uv && uv pip install -r requirements.txt`
59+
6. Install uv and dependencies: `pip install uv && uv sync`
6060
7. Set up the database: `python pythonie/manage.py migrate --settings=pythonie.settings.dev`
6161
8. Generate sample data: `python pythonie/manage.py generate_sample_data --settings=pythonie.settings.dev`
6262
9. Create a superuser: `python pythonie/manage.py createsuperuser --settings=pythonie.settings.dev`
@@ -259,7 +259,7 @@ This project uses several tools to streamline development:
259259

260260
### Import Errors or Module Not Found
261261
- Rebuild Docker image: `task docker:build`
262-
- Reinstall dependencies: `uv pip install -r requirements.txt`
262+
- Reinstall dependencies: `uv sync`
263263

264264
## Contributing
265265

Taskfile.yaml

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -135,40 +135,49 @@ tasks:
135135
cmds:
136136
- docker compose run --rm web python pythonie/manage.py collectstatic
137137

138-
dependencies:compute:
139-
desc: Compute the dependencies
138+
dependencies:lock:
139+
desc: Update uv.lock file from pyproject.toml
140140
cmds:
141-
- toast deps:compute
141+
- uv lock
142142

143-
dependencies:outdated:
144-
desc: List the outdated dependencies
143+
dependencies:upgrade:
144+
desc: Upgrade all dependencies
145145
cmds:
146-
- toast deps:outdated
146+
- uv lock --upgrade
147147

148-
dependencies:upgrade:
149-
desc: Upgrade the dependencies
148+
dependencies:sync:
149+
desc: Install dependencies from lock file (development)
150150
cmds:
151-
- toast deps:upgrade
151+
- uv sync
152152

153-
dependencies:upgrade:django:
154-
desc: Upgrade Django to the latest compatible version
153+
dependencies:sync:production:
154+
desc: Install production dependencies only
155155
cmds:
156-
- toast deps:upgrade:django
156+
- uv sync --no-dev --group production
157157

158-
dependencies:upgrade:wagtail:
159-
desc: Upgrade Wagtail to the latest compatible version
158+
dependencies:export:
159+
desc: Export uv.lock to requirements.txt for Heroku
160160
cmds:
161-
- toast deps:upgrade:wagtail
161+
- uv export --no-dev --group production -o requirements.txt
162+
- uv export --group dev --group production -o requirements-dev.txt
163+
- |
164+
echo "# AUTO-GENERATED from pyproject.toml - DO NOT EDIT" | cat - requirements.txt > temp && mv temp requirements.txt
165+
echo "# AUTO-GENERATED from pyproject.toml - DO NOT EDIT" | cat - requirements-dev.txt > temp && mv temp requirements-dev.txt
166+
167+
dependencies:outdated:
168+
desc: List the outdated dependencies
169+
cmds:
170+
- toast deps:outdated
162171

163172
dependencies:security:
164173
desc: Check dependencies for known security vulnerabilities
165174
cmds:
166-
- toast deps:security
175+
- uv run pip-audit
167176

168177
dependencies:tree:
169178
desc: Show the dependencies tree
170179
cmds:
171-
- toast deps:tree
180+
- uv tree
172181

173182
docker:build:
174183
desc: Build the docker image
@@ -213,9 +222,7 @@ tasks:
213222
dependencies:upgrade:package:
214223
desc: "Upgrade a specific package (usage: task dependencies:upgrade:package PACKAGE=django)"
215224
cmds:
216-
- python -m uv pip compile --upgrade-package $PACKAGE --output-file requirements/main.txt requirements/main.in
217-
- python -m uv pip compile --upgrade-package $PACKAGE --output-file requirements/dev.txt requirements/dev.in
218-
- python -m uv pip compile --upgrade-package $PACKAGE --output-file requirements/production.txt requirements/production.in
225+
- uv lock --upgrade-package {{.PACKAGE}}
219226

220227
tests:
221228
desc: Run all tests

pyproject.toml

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
[build-system]
2+
requires = ["hatchling"]
3+
build-backend = "hatchling.build"
4+
5+
[project]
6+
name = "pythonie"
7+
version = "2.2.0"
8+
description = "Python Ireland website - Django/Wagtail CMS for python.ie and pycon.ie"
9+
readme = "README.md"
10+
requires-python = ">=3.13.0"
11+
license = {text = "MIT"}
12+
authors = [{name = "Python Ireland", email = "[email protected]"}]
13+
keywords = ["django", "wagtail", "cms", "python-ireland", "pycon"]
14+
classifiers = [
15+
"Development Status :: 5 - Production/Stable",
16+
"Framework :: Django :: 5.2",
17+
"Framework :: Wagtail :: 7",
18+
"Programming Language :: Python :: 3.13",
19+
"License :: OSI Approved :: MIT License",
20+
]
21+
22+
# Main production dependencies (from requirements/main.in)
23+
dependencies = [
24+
"Delorean",
25+
"Django",
26+
"Willow",
27+
"boto3",
28+
"colander",
29+
"defusedxml",
30+
"dj-database-url",
31+
"dj-static",
32+
"django-compressor",
33+
"django-extensions",
34+
"django-libsass",
35+
"django-modelcluster",
36+
"django-storages",
37+
"django-taggit",
38+
"gunicorn",
39+
"pandas",
40+
"pydantic",
41+
"python-dateutil",
42+
"pytz",
43+
"redis",
44+
"requests>=2.32.5",
45+
"wagtail",
46+
"whitenoise",
47+
]
48+
49+
# PEP 735 Dependency Groups
50+
[dependency-groups]
51+
# Development dependencies (from requirements/dev.in)
52+
dev = [
53+
"coverage",
54+
"django-debug-toolbar",
55+
"factory-boy",
56+
"fakeredis",
57+
"isort",
58+
"model_mommy",
59+
"pip-audit",
60+
"pipdeptree",
61+
"ruff",
62+
"uv",
63+
]
64+
65+
# Production-specific dependencies (from requirements/production.in)
66+
production = [
67+
"psycopg[binary]",
68+
]
69+
70+
# Tool configurations
71+
[tool.ruff]
72+
target-version = "py313"
73+
line-length = 88
74+
exclude = [
75+
"migrations",
76+
".venv",
77+
"venv",
78+
"pythonie-venv",
79+
".git",
80+
"__pycache__",
81+
]
82+
83+
[tool.ruff.lint]
84+
select = [
85+
"E", # pycodestyle errors
86+
"F", # pyflakes
87+
"I", # isort
88+
"N", # pep8-naming
89+
"W", # pycodestyle warnings
90+
"UP", # pyupgrade
91+
"DJ", # django-specific rules
92+
]
93+
ignore = [
94+
"E501", # Line too long (handled by formatter)
95+
]
96+
97+
[tool.ruff.lint.isort]
98+
known-first-party = ["pythonie", "core", "meetups", "speakers", "sponsors"]
99+
section-order = ["future", "standard-library", "third-party", "django", "wagtail", "first-party", "local-folder"]
100+
101+
[tool.ruff.lint.isort.sections]
102+
"django" = ["django"]
103+
"wagtail" = ["wagtail"]
104+
105+
[tool.ruff.format]
106+
quote-style = "double"
107+
indent-style = "space"
108+
skip-magic-trailing-comma = false
109+
line-ending = "auto"
110+
111+
[tool.coverage.run]
112+
source = ["pythonie"]
113+
omit = [
114+
"*/migrations/*",
115+
"*/tests/*",
116+
"*/test_*.py",
117+
"*/__pycache__/*",
118+
"*/venv/*",
119+
"*/.venv/*",
120+
]
121+
122+
[tool.coverage.report]
123+
exclude_lines = [
124+
"pragma: no cover",
125+
"def __repr__",
126+
"raise AssertionError",
127+
"raise NotImplementedError",
128+
"if __name__ == .__main__.:",
129+
]
130+
131+
[tool.django-stubs]
132+
django_settings_module = "pythonie.settings.dev"
133+
134+
[tool.hatchling.build.targets.wheel]
135+
packages = ["pythonie"]

pythonie/setup.py

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)