uv

Convert to pyproject.toml

Tip

Check existing branches - main may not be the best one to use!

Update uv:

uv self update

Create a branch:

git pull
# Check existing branches - 'main' may not be the best one to use!
git checkout -b 7043-pyproject-toml

Create a pyproject.toml file:

uv init --no-workspace
rm main.py README.md
vim pyproject.toml

# Prepend the 'name' with `kb-'
name = "kb-api"

# Change 'readme' to 'README.rst'
readme = "README.rst"

# python version
requires-python = ">=3.13"

Virtual Environment:

# Create a virtual environment in '.venv' (uv style)
uv venv
# Update 'env' and 'env.fish' to use '.venv' **AND**
set -x PYTHONPATH "src/"
echo "PYTHONPATH: "$PYTHONPATH

Update requirements/base.txt, then add:

uv add -r requirements/base.txt

Remove requirements/base.txt:

git rm -f requirements/base.txt

For an app, remove -r base.txt from requirements/local.txt:

# Remove the following
# --r base.txt

uv add -r requirements/local.txt --group dev
git rm -f requirements/local.txt

# Update '[tool.uv.sources]' to make the apps 'editable' e.g.
kb-base = { path = "../base", editable = true }

For a project:

uv add -r requirements/dev.txt --group dev
# Remove '-r base.txt' from 'requirements/production.txt'
uv add -r requirements/production.txt --group production

Tools in pyproject.toml:

# Add options for pytest - update folder for ``dev_test``!!!
[tool.pytest.ini_options]
addopts= "--ds=settings.dev_test --color=yes --tb=short --show-capture=no -p no:warnings --cov-report html --reuse-db --fail-on-template-vars"
norecursedirs = ".git .venv build"

[tool.ruff]
line-length = 80
indent-width = 4

[[tool.uv.index]]
name = "dev"
url = "http://salt.kb.vpn/kb/dev/+simple/"
default = true
publish-url = "http://salt.kb.vpn/kb/dev/"

Move source code to the src folder:

mkdir src
git mv api src/

Remove old setup files:

git rm setup.cfg setup.py setup.yaml

Update MANIFEST.in (prepend src):

# replace
# recursive-include base/static *
# recursive-include base/templates *
#
# include LICENSE
# include README
# include requirements/*.txt
# include *.ttf
# include *.txt
#
# prune example_base/

# with
recursive-include src/base/static *
recursive-include src/base/templates *

Tip

If you forgot to do this, then make sure to run uv pip install --group dev in the project which uses your app.

Install requirements:

# why does 'uv sync --group dev' remove our apps?
uv pip install --group dev

Make sure the tests are passing:

rm -rf build/; and pytest

Build:

# https://docs.astral.sh/uv/guides/package/#updating-your-version
uv version --bump patch
rm -rf dist/; and uv build

Publish:

# Add the following to '.private.fish'
set -x UV_PUBLISH_USERNAME "my-user"
set -x UV_PUBLISH_PASSWORD "my-pass"

uv publish --index dev

Compare pyproject.toml with an existing version to update as necessary…

Issues

editable

The usual configuration for apps in tool.uv.sources is as follows:

[tool.uv.sources]
kb-api = { path = "../api", editable = true }

Tip

For more information, see Editable dependencies and Path

multiple filesystem locations

This is the error message:

django.core.exceptions.ImproperlyConfigured:
The app module <module 'web' (namespace) from
[
'/home/patrick/dev/project/hatherleigh_info/src/web',
'/home/patrick/dev/project/hatherleigh_info/.venv/lib/python3.13/site-packages/web'
]>
has multiple filesystem locations (
[
'/home/patrick/dev/project/hatherleigh_info/.venv/lib/python3.13/site-packages/web',
'/home/patrick/dev/project/hatherleigh_info/src/web'
]
);
you must configure this app with an AppConfig subclass
with a 'path' class attribute.

To solve the problem, I removed the project from the dev dependency-groups e.g. remove this one:

[dependency-groups]
dev = [
  kb-kbsoftware-couk