UV Python Package And Project Management¶
This document covers my usage of the Python package and project manager UV. Historically, I have used Poetry; however, I am transitioning towards using UV. Hence, this document also covers the transition from Poetry to UV.
Environments & Machine
OS Version: macOS
ProductVersion: 13.3.1
BuildVersion: 22E261
Kernel: arm64
Architecture: 22.4.0
CPU Brand: Apple M1
Python Version: Python 3.13.1
Poetry Version: Poetry (version 1.8.3)
Ruby Version: ruby 3.2.3 (2024-01-18 revision 52bb2ac0a6) [arm64-darwin22]
Installation of UV, on MacOS & Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Description from UV's website:
- 🚀 A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.
- ⚡️ 10-100x faster than pip.
- 🗂️ Provides comprehensive project management, with a universal lockfile.
- ❇️ Runs scripts, with support for inline dependency metadata.
- 🐍 Installs and manages Python versions.
- 🛠️ Runs and installs tools published as Python packages.
- 🔩 Includes a pip-compatible interface for a performance boost with a familiar CLI.
- 🏢 Supports Cargo-style workspaces for scalable projects.
- 💾 Disk-space efficient, with a global cache for dependency deduplication.
- ⏬ Installable without Rust or Python via curl or pip.
- 🖥️ Supports macOS, Linux, and Windows.
Given the speed upgrade and centralization of capabilities, I've decided (2025-05-12) that I will use uv over poetry for Python package and project management.
Useful Links:
- Project Setup & Structure: https://docs.astral.sh/uv/guides/projects/
- Scripting Setup & Running: https://docs.astral.sh/uv/guides/scripts/
- Tooling: https://docs.astral.sh/uv/guides/tools/
- Notes On Using Precommit: https://docs.astral.sh/uv/guides/integration/pre-commit/
- Packaging: https://docs.astral.sh/uv/guides/package/
- Virtual Environments: https://docs.astral.sh/uv/pip/environments/
Porting Over From UV To Poetry:
- Install
uv(see above), if it's not already installed, and navigate to the target repository. - Skip the next sub-steps if the
poetryversion is less than version 2.0. - Check to see if the following is in
pyproject.toml; if the lines are not present[^more], add them:
[tool.poetry.requires-plugins]
poetry-plugin-export = ">=1.8"
[^more]: For more information on poetry plugins, see here; for more information on the export command, see here.
- Run
poetry install. - Check the
pyproject.tomlfile for different groups, such asdevandtest; run the following command with the groups you want:
poetry export \
--format=requirements.txt \
--without-hashes \
--with dev,test \
--output=requirements.txt
- Create a
projectsection in thepyprojectfile (see standard below) - If a section is not made, then the error when you run the next command might look like: "No
projecttable found in ...".
Standard Pyproject Project Table
[project]
name = ""
version = ""
authors = [
{name = "", email = ""},
]
description = ""
readme = ""
license = ""
keywords = [""]
requires-python = ">=3.13"
[project.urls]
Repository = ""
Issues = ""
"Author GitHub" = ""
classifiers = ["Private :: Do Not Upload"]
- Remove items with
poetryin the header: tool.poetry.dependenciestool.poetry.group.dev.dependencies- This includes removing:
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
- Delete the
poetry.lockfile and remove it from the.gitignore. - Add a file called
.python-versionwith the version (e.g. 3.13) you want. - Run
uv python pin 3.13. - Ensure the
requirements.txtfile has the dependencies of interest before running:
uv add --requirements requirements.txt
- Run
uv lock. - Add the following to the
.pre-commit-config.yamlfile, if there is one and if not already present:
- repo: https://github.com/astral-sh/uv-pre-commit
# uv version.
rev: 0.7.3
hooks:
- id: uv-lock
- Don't delete the
requirements.txtfile, since other Python users might still want to use this; if you agree with the previous statement, add the following to the.pre-commit-config.yamlfile:
- id: uv-export
args: ["--no-hashes", "--output-file=requirements.txt"]
- Run
uv venvto create virtual environment. - Run
source .venv/bin/activateto activate. - Run
deactivateto deactivate.
Some UV Basics:
- Create a
venv:uv venv - Activate the
venv:source .venv/bin/activate - Deactivate the
venv:deactivate - Add a package:
uv add <package>(being insidevenvno necessary) - Remove a package:
uv remove <package> - Update state of dependencies after package edit:
uv sync - Check packages installed:
uv pip list - Dependency graph:
uv tree - Check the lock file:
uv lock --check
Full Poetry To UV Instructions:
The below are condensed and will not fully generalize, but are still useful.
poetry install
poetry export \
--format=requirements.txt \
--without-hashes \
--with dev,test \
--output=requirements.txt
(delete poetry items)
uv python pin 3.13
[project]
name = ""
version = ""
authors = [
{name = "", email = ""},
]
description = ""
readme = ""
license = ""
keywords = [""]
requires-python = ">=3.13"
classifiers = ["Private :: Do Not Upload"]
[project.urls]
Repository = ""
Issues = ""
"Author GitHub" = ""
uv add --requirements requirements.txt
################################################################################
# UV PACKAGE AND DEPENDENCY MANAGEMENT
################################################################################
- repo: https://github.com/astral-sh/uv-pre-commit
# uv version.
rev: 0.7.3
hooks:
- id: uv-lock
- id: uv-export
args: ["--no-hashes", "--output-file=requirements.txt"]
uv lock
uv venv
uv sync