Skip to content

Commit 94aca4e

Browse files
committed
update python uv cheat sheet
1 parent 03b9cd9 commit 94aca4e

1 file changed

Lines changed: 122 additions & 33 deletions

File tree

docs/posts/2025/2025-08-26-python-uv-cheat-sheet.md

Lines changed: 122 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,29 @@ categories:
77
comments: true
88
date:
99
created: 2025-08-26
10+
updated: 2025-08-28
1011
---
1112

1213
# Python uv cheat sheet
1314

14-
Python [UV](https://docs.astral.sh/uv/) common usage cheat sheet, but doesn't cover all the features.
15+
Python [uv](https://docs.astral.sh/uv/) common usage cheat sheet, but doesn't cover all the features.
1516

1617
<!-- more -->
1718

1819
## Init project
1920

20-
```bash
21-
# init new project with new folder
22-
uv init my-project -p python3.13
21+
uv init can have 3 templates: [`--app`](https://docs.astral.sh/uv/concepts/projects/init/#packaged-applications) (by default), [`--lib`](https://docs.astral.sh/uv/concepts/projects/init/#applications) and [`--package`](https://docs.astral.sh/uv/concepts/projects/init/#packaged-applications).
22+
23+
| Command | Description |
24+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
25+
| `uv init my-project -p python3.13` | Init new project with new folder |
26+
| `uv init -p python3.13` | Init an existing project with python3.13 |
27+
| `uv init --lib` | Libraries template creates a src folder whereas application template only creates a main.py file |
28+
| `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` |
2329

24-
# init an existing project
25-
uv init -p python3.13
30+
```toml title="pyproject.toml created by uv init --package pkg-1"
31+
[project.scripts]
32+
pkg-1 = "pkg_1:main"
2633
```
2734

2835
!!! warning "uv init under a folder with already a pyproject.toml"
@@ -39,7 +46,7 @@ Ref:
3946

4047
> `optional-dependencies` are part of the published metadata for your package, while `dependency-groups` are only visible when working with your package locally
4148
42-
### Add to dependencies
49+
### Add to project.dependencies as main dependencies
4350

4451
```bash
4552
uv add fastapi
@@ -56,10 +63,10 @@ dependencies = [
5663
]
5764
```
5865

59-
### Add to optional dependencies as extra packages
66+
### Add to project.optional-dependencies as extra packages
6067

6168
```bash
62-
uv add ruff --optional aio
69+
uv add aiohttp --optional aio
6370
```
6471

6572
Could be installed by end users with `uv pip install temp[aio]`
@@ -74,7 +81,7 @@ aio = [
7481
]
7582
```
7683

77-
### Add to dependency groups
84+
### Add to dependency-groups for local development
7885

7986
```bash
8087
uv add ruff --dev
@@ -100,6 +107,53 @@ typing = [
100107

101108
```
102109

110+
### Add to dependency sources
111+
112+
[Dependency sources](https://docs.astral.sh/uv/concepts/projects/dependencies/#dependency-sources) are for local development only.
113+
114+
```bash
115+
uv add git+https://github.com/encode/httpx
116+
uv add --editable ../temp1/lib_1
117+
```
118+
119+
```toml
120+
[project]
121+
name = "temp"
122+
...
123+
[tool.uv.sources]
124+
httpx = { git = "https://github.com/encode/httpx" }
125+
lib-1 = { path = "../temp1/lib_1", editable = true }
126+
```
127+
128+
!!! note
129+
For multiple packages in the same repository, [workspaces](https://docs.astral.sh/uv/concepts/projects/workspaces/) may be a better fit.
130+
131+
### Declare conflicting dependencies
132+
133+
uv supports explicit [declaration of conflicting dependency groups](https://docs.astral.sh/uv/concepts/projects/config/#conflicting-dependencies). For example, to declare that the optional-dependency groups extra1 and extra2 are incompatible:
134+
135+
```toml title="pyproject.toml"
136+
[tool.uv]
137+
conflicts = [
138+
[
139+
{ extra = "extra1" },
140+
{ extra = "extra2" },
141+
],
142+
]
143+
```
144+
145+
Or, to declare the development dependency groups group1 and group2 incompatible:
146+
147+
```toml title="pyproject.toml"
148+
[tool.uv]
149+
conflicts = [
150+
[
151+
{ group = "group1" },
152+
{ group = "group2" },
153+
],
154+
]
155+
```
156+
103157
## Install dependencies
104158

105159
```toml title="pyproject.toml"
@@ -141,40 +195,63 @@ all = [
141195

142196
!!! note "use `uv sync --dry-run` to see what will be the changes"
143197

144-
- Install dependencies only: `uv sync --no-dev` (without any extra nor any group)
145-
- Install dependencies and `dev` group: `uv sync`
146-
- Install dependencies and all groups (dependency-groups): `uv sync --all-groups`
147-
- Install dependencies and all extras (project.optional-dependencies) and `dev` group: `uv sync --all-extras` (`dev` group is by default)
148-
- Install dependencies and all extras and all groups: `uv sync --all-extras --all-groups`
149-
- Install dependencies and extra `aio` and `dev` group: `uv sync --extra aio`
150-
- Install dependencies and extra `aio` but without `dev` group: `uv sync --extra aio --no-dev`
151-
- Install dependencies and `dev` groups and already installed extraneous packages not declared in pyproject.toml: `uv sync --extra aio --inexact`
198+
| Command | Description |
199+
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
200+
| `uv sync --no-dev` | Install [dependencies](https://docs.astral.sh/uv/concepts/projects/dependencies/#project-dependencies) only (without any extra nor any group) |
201+
| `uv sync` | Install dependencies and `dev` group, no extras, no other groups than `dev` |
202+
| `uv sync --all-groups` | Install dependencies and all groups ([`dependency-groups`](https://docs.astral.sh/uv/concepts/projects/dependencies/#dependency-groups)) |
203+
| `uv sync --all-extras` | Install dependencies and all extras ([`project.optional-dependencies`](https://docs.astral.sh/uv/concepts/projects/dependencies/#optional-dependencies)) and `dev` group (`dev` group is by default) |
204+
| `uv sync --all-extras --all-groups` | Install dependencies and all extras and all groups |
205+
| `uv sync --extra aio` | Install dependencies and extra `aio` and `dev` group |
206+
| `uv sync --extra aio --no-dev` | Install dependencies and extra `aio` but without `dev` group |
207+
| `uv sync --extra aio --inexact` | Install dependencies and `dev` groups and retain already installed [extraneous packages](https://docs.astral.sh/uv/concepts/projects/sync/#retaining-extraneous-packages) not declared in pyproject.toml |
208+
| `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.<br/><br/>In 🐳 Dockerfile ([official uv Dockerfile example](https://github.com/astral-sh/uv-docker-example/blob/main/Dockerfile)), we often use `uv sync --locked --no-install-project --no-dev`, see [Using uv in Docker](https://docs.astral.sh/uv/guides/integration/docker/) to understand the usage of each parameters. |
209+
| | |
210+
211+
```bash
212+
$ uv sync --locked --no-dev
213+
Resolved 21 packages in 33ms
214+
The lockfile at `uv.lock` needs to be updated, but `--locked` was provided.
215+
To update the lockfile, run `uv lock`.
216+
```
217+
218+
### `--locked` vs `--frozen` vs `--no-sync`
219+
220+
official doc: https://docs.astral.sh/uv/concepts/projects/sync/#automatic-lock-and-sync
152221

153-
- Ensure install by respecting `uv.lock` (ensure uv.lock won't be changed after uv sync) and raise error if lock file doesn't conform with pyproject.toml: `uv sync --locked --no-dev`, in Dockerfile ([official uv Dockerfile example](https://github.com/astral-sh/uv-docker-example/blob/main/Dockerfile)), we often use `uv sync --locked --no-install-project --no-dev`, see [Using uv in Docker](https://docs.astral.sh/uv/guides/integration/docker/) to understand the usage of each parameters.
222+
`uv.lock` file related:
154223

155-
```bash
156-
$ uv sync --locked --no-dev
157-
Resolved 21 packages in 33ms
158-
The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`.
159-
```
224+
- `--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`.
225+
- `--frozen`: Use the lockfile without checking if it is up-to-date, no error will be raised.
226+
227+
`venv` related:
228+
229+
- `--no-sync`: Do not update the venv.
160230

161231
## Dependencies tree
162232

163-
- `uv pip tree`: display the **installed packages** in a tree format.
164-
- `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 tree pip tree`
165-
- `uv tree --frozen`: don't update `uv.lock`, just display tree based on the current `uv.lock`
166-
- `uv tree --locked`: if `uv.lock` is not updated, display a warning message. This command is not very useful.
233+
| Command | Description |
234+
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
235+
| `uv pip tree` | Display the **installed packages** in a tree format |
236+
| `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` |
237+
| `uv tree --frozen` | Don't update `uv.lock`, just display tree based on the current `uv.lock` |
238+
| `uv tree --locked` | If `uv.lock` is not updated, display a warning message. This command is not very useful |
167239

168240
## List outdated packages
169241

170-
- `uv tree --outdated`: display a list of outdated packages with their latest versions.
242+
- `uv tree --outdated`: display a list of outdated packages with their latest **public** versions, no matter what `pyproject.toml` declares.
243+
- [`uv lock --check`](https://docs.astral.sh/uv/concepts/projects/sync/#checking-if-the-lockfile-is-up-to-date): check if `uv.lock` is up-to-date with `pyproject.toml`.
171244

172245
## Upgrade packages and uv.lock
173246

174-
- `uv lock`: update the `uv.lock` file to match the current state of `pyproject.toml`.
175-
- `uv lock -U`: update the `uv.lock` file and upgrade all packages to their latest compatible versions.
176-
- `uv sync`: same as `uv lock` but also installs the dependencies.
177-
- `uv sync -U`: same as `uv lock -U` but also installs the dependencies.
247+
[`uv.lock` file](https://docs.astral.sh/uv/concepts/projects/layout/#the-lockfile)can be updated by `uv lock`, `uv sync`, `uv run`, `uv add`, `uv remove`.
248+
249+
| Command | Description |
250+
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
251+
| `uv lock` | Update the `uv.lock` file to match the current state of `pyproject.toml` |
252+
| `uv lock -U` | Update the `uv.lock` file and [upgrade](https://docs.astral.sh/uv/concepts/projects/sync/#upgrading-locked-package-versions) all packages to their latest compatible versions |
253+
| `uv sync` | Same as `uv lock` but also installs the dependencies |
254+
| `uv sync -U` | Same as `uv lock -U` but also installs the dependencies |
178255

179256
!!! note "`uv lock` vs `uv lock -U` and `uv sync` vs `uv sync -U`"
180257
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:
@@ -184,6 +261,18 @@ all = [
184261

185262
Same logic applies to `uv sync` and `uv sync -U`, except for `sync` installing the dependencies too.
186263

264+
`-U` (`--upgrade` for all packages) or `-P` (`--upgrade-package` for a specific package) respect always the version constraints defined in `pyproject.toml`.
265+
187266
## Integrations
188267

189268
Check [this doc](https://docs.astral.sh/uv/guides/integration/) for more information on integrations with other tools and platforms (Docker, Jupyter, Github Actions, Pre Commit, PyTorch FastAPI, etc.).
269+
270+
## Build
271+
272+
### Build with rust, C, C++, CPython backend
273+
274+
uv can also [build with extension module by `--build-backend` flag](https://docs.astral.sh/uv/concepts/projects/init/#projects-with-extension-modules) to work with Rust and C, C++, CPython etc.
275+
276+
### Build isolation
277+
278+
uv build isolation is by default, but some packages need to [build against the same version of some packages installed in the project environment](https://docs.astral.sh/uv/concepts/projects/config/#build-isolation). For example, [flask-attn](https://pypi.org/project/flash-attn/), [deepspeed](https://pypi.org/project/deepspeed/), [cchardet](https://pypi.org/project/cchardet/), etc.

0 commit comments

Comments
 (0)