|
| 1 | +--- |
| 2 | +authors: |
| 3 | +- copdips |
| 4 | +categories: |
| 5 | +- python |
| 6 | +- package |
| 7 | +comments: true |
| 8 | +date: |
| 9 | + created: 2025-08-26 |
| 10 | +--- |
| 11 | + |
| 12 | +# Python uv cheat sheet |
| 13 | + |
| 14 | +Python [UV](https://docs.astral.sh/uv/) common usage cheat sheet, but doesn't cover all the features. |
| 15 | + |
| 16 | +<!-- more --> |
| 17 | + |
| 18 | +## Init project |
| 19 | + |
| 20 | +```bash |
| 21 | +# init new project with new folder |
| 22 | +uv init my-project -p python3.13 |
| 23 | + |
| 24 | +# init an existing project |
| 25 | +uv init -p python3.13 |
| 26 | +``` |
| 27 | + |
| 28 | +!!! warning "uv init under a folder with already a pyproject.toml" |
| 29 | + 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. |
| 30 | + |
| 31 | +## Add dependencies |
| 32 | + |
| 33 | +### optional-dependencies vs dependency-groups |
| 34 | + |
| 35 | +Ref: |
| 36 | + |
| 37 | +- [UV's Dependency fields](https://docs.astral.sh/uv/concepts/projects/dependencies/#dependency-fields) |
| 38 | +- https://github.com/astral-sh/uv/issues/8981#issuecomment-2466787211 |
| 39 | + |
| 40 | + > `optional-dependencies` are part of the published metadata for your package, while `dependency-groups` are only visible when working with your package locally |
| 41 | +
|
| 42 | +### Add to dependencies |
| 43 | + |
| 44 | +```bash |
| 45 | +uv add fastapi |
| 46 | +``` |
| 47 | + |
| 48 | +Could be installed by end users with `uv pip install temp` |
| 49 | + |
| 50 | +```toml title="pyproject.toml" |
| 51 | +[project] |
| 52 | +name = "temp" |
| 53 | +... |
| 54 | +dependencies = [ |
| 55 | + "fastapi>=0.116.1", |
| 56 | +] |
| 57 | +``` |
| 58 | + |
| 59 | +### Add to optional dependencies as extra packages |
| 60 | + |
| 61 | +```bash |
| 62 | +uv add ruff --optional aio |
| 63 | +``` |
| 64 | + |
| 65 | +Could be installed by end users with `uv pip install temp[aio]` |
| 66 | + |
| 67 | +```toml title="pyproject.toml" |
| 68 | +[project] |
| 69 | +name = "temp" |
| 70 | +... |
| 71 | +[project.optional-dependencies] |
| 72 | +aio = [ |
| 73 | + "aiohttp>=3.12.15", |
| 74 | +] |
| 75 | +``` |
| 76 | + |
| 77 | +### Add to dependency groups |
| 78 | + |
| 79 | +```bash |
| 80 | +uv add ruff --dev |
| 81 | +# or |
| 82 | +uv add ruff --group dev |
| 83 | + |
| 84 | +uv add ty --group typing |
| 85 | +``` |
| 86 | + |
| 87 | +Dependencies declared in the `dependency-groups` part are not added to the package metadata, so end users cannot install them directly. |
| 88 | + |
| 89 | +```toml title="pyproject.toml" |
| 90 | +[project] |
| 91 | +name = "temp" |
| 92 | +... |
| 93 | +[dependency-groups] |
| 94 | +dev = [ |
| 95 | + "ruff>=0.12.4", |
| 96 | +] |
| 97 | +typing = [ |
| 98 | + "ty>=0.0.1a19", |
| 99 | +] |
| 100 | + |
| 101 | +``` |
| 102 | + |
| 103 | +## Install dependencies |
| 104 | + |
| 105 | +```toml title="pyproject.toml" |
| 106 | +[project] |
| 107 | +name = "temp" |
| 108 | +version = "0.1.0" |
| 109 | +description = "Add your description here" |
| 110 | +readme = "README.md" |
| 111 | +requires-python = ">=3.13" |
| 112 | +dependencies = [ |
| 113 | + "fastapi>=0.116.1", |
| 114 | +] |
| 115 | + |
| 116 | +# this is the optional extra part, useful for end user |
| 117 | +[project.optional-dependencies] |
| 118 | +aio = [ |
| 119 | + "aiohttp>=3.12.15", |
| 120 | +] |
| 121 | + |
| 122 | +# this is the local development groups part, useful for developers |
| 123 | +[dependency-groups] |
| 124 | +dev = [ |
| 125 | + "ruff>=0.12.4", |
| 126 | +] |
| 127 | +typing = [ |
| 128 | + "ty>=0.0.1a19", |
| 129 | +] |
| 130 | +all = [ |
| 131 | + {include-group = "dev"}, |
| 132 | + {include-group = "typing"}, |
| 133 | +] |
| 134 | +``` |
| 135 | + |
| 136 | +!!! note "The `--dev`, `--only-dev`, and `--no-dev` flags are equivalent to `--group dev`, `--only-group dev`, and `--no-group dev` respectively." |
| 137 | + |
| 138 | +!!! note "without `--no-dev`, the `dev` group is already installed with `uv sync`" |
| 139 | + Use `uv sync --no-dev` or `uv sync --no-default-groups` to avoid installing the `dev` group. |
| 140 | + By default, [uv includes the `dev` dependency group](https://docs.astral.sh/uv/concepts/projects/dependencies/#default-groups) 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. |
| 141 | + |
| 142 | +!!! note "use `uv sync --dry-run` to see what will be the changes" |
| 143 | + |
| 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` |
| 152 | + |
| 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](https://github.com/astral-sh/uv-docker-example/blob/main/Dockerfile), we often use `uv sync --locked --no-install-project --no-dev` |
| 154 | + |
| 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 | + ``` |
| 160 | + |
| 161 | +## Dependencies tree |
| 162 | + |
| 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. |
| 167 | +
|
| 168 | +## List outdated packages |
| 169 | +
|
| 170 | +- `uv tree --outdated`: display a list of outdated packages with their latest versions. |
| 171 | +
|
| 172 | +## Upgrade packages and uv.lock |
| 173 | +
|
| 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. |
| 178 | +
|
| 179 | +!!! note "`uv lock` vs `uv lock -U` and `uv sync` vs `uv sync -U`" |
| 180 | + 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: |
| 181 | +
|
| 182 | + - `uv lock`: no effect, as `0.115.1` is still within the range of `>=0.115.1`. |
| 183 | + - `uv lock -U`: upgrade `fastapi` to `0.116.1`. |
| 184 | +
|
| 185 | + Same logic applies to `uv sync` and `uv sync -U`, except for `sync` installing the dependencies too. |
| 186 | +
|
| 187 | +## Integrations |
| 188 | +
|
| 189 | +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.). |
0 commit comments