python uv - ghdrako/doc_snipets GitHub Wiki

Install

# On macOS and Linux.
curl -LsSf https://astral.sh/uv/install.sh | sh

# On Windows.
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Update

$ uv self update

Initializing a new project

$ uv init explore-uv
$ cd explore-uv
$ tree -a
.
├── .gitignore
├── .python-version
├── README.md
├── hello.py
└── pyproject.toml

Git is automatically initialized and main git-related files like .gitignore and an empty README.md are generated. .python-version file contains the Python version used for the project, while pyproject.toml serves as the main configuration file for project metadata and dependencies.

Using uv in existing project

navigate to the project directory and run the following command

$ uv init

This command will create the uv project structure for you. It won’t overwrite the main.py file if you have one, but it’ll create the file if it’s missing. It neither modifies your Git repository nor your README.md file.

However, this command won’t work if you already have a pyproject.toml file in place.

Adding initial dependencies to the project

$ uv add scikit-learn xgboost

The first time you run the add command, UV creates a new virtual environment in the current working directory and installs the specified dependencies. On subsequent runs, UV will reuse the existing virtual environment and only install or update the newly requested packages, ensuring efficient dependency management.

UV uses a modern dependency resolver that analyzes the entire dependency graph to find a compatible set of package versions that satisfy all requirements. The resolver considers factors like version constraints, Python version compatibility, and platform-specific requirements to determine the optimal set of packages to install.

UV also updates the pyproject.toml and uv.lock files after each add command.

$ cat pyproject.toml
[project]
name = "explore-uv"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.9"
dependencies = [
    "scikit-learn>=1.5.2",
    "xgboost>=2.0.3",
]

upgrade a dependency

$ uv add --upgrade requests

remove a dependency

$ uv remove scikit-learn

remove a dependency from the environment and the pyproject.toml file

development dependency

If project doesn’t need library to run, you can install it as a development dependency

$ uv add --dev pytest

list dependency

$ uv pip list
$ uv lock
$ uv sync

Running Python scripts with UV

$ uv run hello.py

The run command ensures that the script is executed inside the virtual environment UV created for the project.

Managing Python Versions in UV

Listing existing Python versions

$ uv python list --only-installed

UV can discover existing installations by default.

Changing Python versions for the current project

$vi .python-version
...
requires-python = ">=3.9"


$ uv sync

The command first checks against existing Python installations. If the requested version isn't found, UV downloads and installs it inside the /Users/username/.local/share/uv/python path. UV also creates a new virtual environment inside the project directory, replacing the old one.

This new environment doesn't have the dependencies listed in your pyproject.toml file, so you have to install them with the following command:

$ uv pip install -e .

UV tools

Some Python packages are exposed as command-line tools. UV provides two special interfaces to manage these packages:

  1. Using uv tool run:
$ uv tool run black hello.py
  1. Using the shorter and more convenient uvx command:
$ uvx black hello.py

When these commands are run, UV creates a temporary virtual environment in its cache. The requested tool is installed and run from there. In other words, you can use command-line tools without installing them in the project's virtual environment, resulting in faster execution and cleaner project dependencies.

Perfect for occasional use of development tools.

Lock Files in UV

ock files (uv.lock) are an essential part of dependency management in UV.The lock file should be committed to version control to ensure all developers use the same dependency versions.

You can maintain both files by using UV's lock file for development while generating a requirements.txt for deployment. To generate a requirements.txt from a UV lock file, use the following command:

$ uv export -o requirements.txt

Dependency Management With UV

  1. Installing the latest version of a package:
$ uv add requests
  1. Installing a specific version:
$ uv add requests=2.1.2
  1. Change the bounds of a package's constraints:
$ uv add 'requests<3.0.0'
  1. Make a dependency platform-specific:
$ uv add 'requests; sys_platform="linux"' 

Adding optional dependencies

Optional dependencies are packages that are not required for the core functionality of your project but may be needed for specific features. For example, Pandas has an excel extra and a plot extra to avoid the installation of Excel parsers and matplotlib unless someone explicitly requires them. Optionals are usually installed with the pip install pandas[plot, excel] syntax.

$ uv add pandas  # install core package
$ uv add pandas --optional plot excel

Dependency groups

Dependency groups allow you to organize your dependencies into logical groups, such as development dependencies, test dependencies, or documentation dependencies. This is useful for keeping your production dependencies separate from your development dependencies.

To add a dependency to a specific group, use the --group flag:

$ uv add --group group_name package_name

Then, users will be able to control which groups to install using the --group, --only-group, and --no-group tags.

pip/virtualenv command UV equivalent
python -m venv .venv uv venv
pip install package uv add package
pip install -r requirements.txt uv pip install -r requirements.txt
pip uninstall package uv remove package
pip freeze uv pip freeze
pip list uv pip list

Building and Publishing Packages

Configuring the Project

[project]
name = "rpcats"
version = "0.1.0"
description = "Display cat information for the specified breed."
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
    "requests>=2.32.3",
]

[dependency-groups]
dev = [
    "pytest>=8.3.5",
]

[project.scripts]
rpcats = "main:main"

With these two additional last lines, you ensure that when someone installs your app, they can run the rpcats command from their terminal to execute the code from the main() function, which is stored in the main.py file.

define a build system

...
[project.scripts]
rpcats = "main:main"

[build-system]
requires = ["setuptools>=78.1.0", "wheel>=0.45.1"]
build-backend = "setuptools.build_meta"

Building a Distribution

$ uv build

You also have the following build options:

  • uv build --sdist
  • uv build --wheel

The first command builds a source distribution only, while the second command builds a binary distribution. Note that using uv build without any flags will build both the source and binary distributions.

Publishing a Distribution

...
[build-system]
requires = ["setuptools>=78.1.0", "wheel>=0.45.1"]
build-backend = "setuptools.build_meta"

[tool.uv.index](/ghdrako/doc_snipets/wiki/tool.uv.index)
name = "testpypi"
url = "https://test.pypi.org/simple/"
publish-url = "https://test.pypi.org/legacy/"
explicit = true

you can use uv publish with the --index option to upload your app to TestPyPI:

$ uv publish --index testpypi --token your_token_here

To run this command, you’ll need to add your personal API token for TestPyPI following the --token option. Once you’ve entered all the information, press Enter to upload the app to TestPyPI.