Python uv cheat sheet#
Python uv common usage cheat sheet, but doesn't cover all the features.
Init project#
uv init can have 3 templates: --app
(by default), --lib
and --package
.
Command | Description |
---|---|
uv init my-project -p python3.13 | Init new project with new folder |
uv init -p python3.13 | Init an existing project with python3.13 |
uv init --lib | Libraries template creates a src folder whereas application template only creates a main.py file |
uv init --package | Init a project with package template, same as libraries but pyproject.toml has a [project.scripts] key, so this is for command-line interface you can later run the command by: uv run pkg-1 |
uv init under a folder with already a pyproject.toml
If upper folders has already a pyproject.toml
file, uv will also add the new project (created by uv init
) as [tool.uv.workspace]
members. This cheat sheet doesn't cover that. As that makes uv workspace management more complex. You might need to use uv sync --active
to install dependencies in the separate venv of the sub module if needed.
Add dependencies#
optional-dependencies vs dependency-groups#
Ref:
optional-dependencies
are part of the published metadata for your package, whiledependency-groups
are only visible when working with your package locally
Add to project.dependencies as main dependencies#
Could be installed by end users with uv pip install temp
Add to project.optional-dependencies as extra packages#
Could be installed by end users with uv pip install temp[aio]
[project]
name = "temp"
...
[project.optional-dependencies]
aio = [
"aiohttp>=3.12.15",
]
Add to dependency-groups for local development#
Dependencies declared in the dependency-groups
part are not added to the package metadata, so end users cannot install them directly.
[project]
name = "temp"
...
[dependency-groups]
dev = [
"ruff>=0.12.4",
]
typing = [
"ty>=0.0.1a19",
]
Add to dependency sources#
Dependency sources are for local development only.
[project]
name = "temp"
...
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx" }
lib-1 = { path = "../temp1/lib_1", editable = true }
Note
For multiple packages in the same repository, workspaces may be a better fit.
Declare conflicting dependencies#
uv supports explicit declaration of conflicting dependency groups. For example, to declare that the optional-dependency groups extra1 and extra2 are incompatible:
Or, to declare the development dependency groups group1 and group2 incompatible:
Install dependencies#
[project]
name = "temp"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"fastapi>=0.116.1",
]
# this is the optional extra part, useful for end user
[project.optional-dependencies]
aio = [
"aiohttp>=3.12.15",
]
# this is the local development groups part, useful for developers
[dependency-groups]
dev = [
"ruff>=0.12.4",
]
typing = [
"ty>=0.0.1a19",
]
all = [
{include-group = "dev"},
{include-group = "typing"},
]
The --dev
, --only-dev
, and --no-dev
flags are equivalent to --group dev
, --only-group dev
, and --no-group dev
respectively.
without --no-dev
, the dev
group is already installed with uv sync
Use uv sync --no-dev
or uv sync --no-default-groups
to avoid installing the dev
group. By default, uv includes the dev
dependency group in the environment (e.g., during uv run
or uv sync
). The default groups to include can be changed using the tool.uv.default-groups
setting.
use uv sync --dry-run
to see what will be the changes
Command | Description |
---|---|
uv sync --no-dev | Install dependencies only (without any extra nor any group) |
uv sync | Install dependencies and dev group, no extras, no other groups than dev |
uv sync --all-groups | Install dependencies and all groups (dependency-groups ) |
uv sync --all-extras | Install dependencies and all extras (project.optional-dependencies ) and dev group (dev group is by default) |
uv sync --all-extras --all-groups | Install dependencies and all extras and all groups |
uv sync --extra aio | Install dependencies and extra aio and dev group |
uv sync --extra aio --no-dev | Install dependencies and extra aio but without dev group |
uv sync --extra aio --inexact | Install dependencies and dev groups and retain already installed extraneous packages not declared in pyproject.toml |
uv sync --locked --no-dev | Ensure install by respecting uv.lock (ensure uv.lock won't be changed after uv sync) and raise an error if lock file doesn't confirm with pyproject.toml.In 🐳 Dockerfile (official uv Dockerfile example), we often use uv sync --locked --no-install-project --no-dev , see Using uv in Docker to understand the usage of each parameters. |
$ uv sync --locked --no-dev
Resolved 21 packages in 33ms
The lockfile at `uv.lock` needs to be updated, but `--locked` was provided.
To update the lockfile, run `uv lock`.
--locked
vs --frozen
vs --no-sync
#
official doc: https://docs.astral.sh/uv/concepts/projects/sync/#automatic-lock-and-sync
uv.lock
file related:
--locked
: If the lockfile is not up-to-date, uv will raise an error instead of updating the lockfile.--locked
could be considered as--ensure-locked
.--frozen
: Use the lockfile without checking if it is up-to-date, no error will be raised.
venv
related:
--no-sync
: Do not update the venv.
Dependencies tree#
Command | Description |
---|---|
uv pip tree | Display the installed packages in a tree format |
uv tree | Update uv.lock based on pyproject.toml and display tree based on uv.lock , no package installation will occur. uv tree displays better than uv pip tree |
uv tree --frozen | Don't update uv.lock , just display tree based on the current uv.lock |
uv tree --locked | If uv.lock is not updated, display a warning message. This command is not very useful |
List outdated packages#
uv tree --outdated
: display a list of outdated packages with their latest public versions, no matter whatpyproject.toml
declares.uv lock --check
: check ifuv.lock
is up-to-date withpyproject.toml
.
Upgrade packages and uv.lock#
uv.lock
filecan be updated by uv lock
, uv sync
, uv run
, uv add
, uv remove
.
Command | Description |
---|---|
uv lock | Update the uv.lock file to match the current state of pyproject.toml |
uv lock -U | Update the uv.lock file and upgrade all packages to their latest compatible versions |
uv sync | Same as uv lock but also installs the dependencies |
uv sync -U | Same as uv lock -U but also installs the dependencies |
uv lock
vs uv lock -U
and uv sync
vs uv sync -U
If latest version of fastapi is 0.116.1, and pyproject.toml declares fastapi>=0.115.1, and current uv.lock has fastapi==0.115.1. then:
uv lock
: no effect, as0.115.1
is still within the range of>=0.115.1
.uv lock -U
: upgradefastapi
to0.116.1
.
Same logic applies to uv sync
and uv sync -U
, except for sync
installing the dependencies too.
-U
(--upgrade
for all packages) or -P
(--upgrade-package
for a specific package) respect always the version constraints defined in pyproject.toml
.
Integrations#
Check this doc for more information on integrations with other tools and platforms (Docker, Jupyter, Github Actions, Pre Commit, PyTorch FastAPI, etc.).
Build#
Build with rust, C, C++, CPython backend#
uv can also build with extension module by --build-backend
flag to work with Rust and C, C++, CPython etc.
Build isolation#
uv build isolation is by default, but some packages need to build against the same version of some packages installed in the project environment. For example, flask-attn, deepspeed, cchardet, etc.