cheat-sheets

Python and uv

uv is a fast Python package and project manager (written in Rust) that replaces pip, venv, pip-tools, pipx and most of pyenv with one tool. This sheet covers uv first, then the plain venv and pip basics it builds on. Use Python for scripts that outgrow Bash, especially anything that parses JSON (jq covers the shell side) or calls HTTP APIs (curl for quick tests).

Documentation: uv docs, Python venv, PEP 723 inline script metadata

Install #

COMMANDDESCRIPTION
curl -LsSf https://astral.sh/uv/install.sh | shStandalone installer (Linux and macOS)
brew install uvHomebrew
pipx install uvVia pipx
uv self updateUpdate uv (standalone install only)
uv --versionVerify
uv generate-shell-completion bashPrint shell completion script

Projects #

COMMANDDESCRIPTION
uv init <NAME>New project with pyproject.toml
uv initInitialise the current directory
uv init --app / --libApplication (default) or packaged library layout
uv init --script <FILE.py>New standalone script with inline metadata
uv add <PKG>Add a dependency (updates pyproject.toml and uv.lock)
uv add '<PKG>>=2,<3'Add with a version constraint
uv add --dev <PKG>Add a development dependency
uv add -r requirements.txtImport from a requirements file
uv add --group <GROUP> <PKG>Add to a named dependency group
uv add <PKG> --optional <EXTRA>Add to an optional-dependencies extra
uv add --editable ./<PATH>Add a local package as an editable dependency
uv remove <PKG>Remove a dependency
uv syncCreate .venv and install exactly what the lockfile says
uv sync --frozenInstall from the lockfile without updating it
uv sync --lockedFail if the lockfile is out of date (CI)
uv sync --no-dev / --only-devSkip, or install only, the dev group
uv sync --extra <EXTRA> / --all-extrasInclude optional dependencies
uv sync --group <GROUP> / --all-groupsInclude dependency groups (--only-group, --no-group also exist)
uv sync --no-install-projectInstall dependencies but not the project itself (Docker layer caching)
uv sync --no-install-package <PKG>Skip one package
uv sync --inexactKeep extraneous packages instead of removing them
uv lockUpdate uv.lock only
uv lock --upgradeUpgrade all locked versions
uv lock --upgrade-package <PKG>Upgrade one package
uv lock --upgrade-package '<PKG>==<VERSION>'Move one package to a specific version
uv lock --checkFail if the lockfile is out of date (same as --locked)
uv run <CMD>Run in the project environment (syncs first)
uv run python -m pytestRun a tool from the environment
uv treeDependency tree
uv export --format requirements-txt > requirements.txtExport for tools that need it
uv buildBuild sdist and wheel
uv publishUpload to PyPI

Commit pyproject.toml and uv.lock; do not commit .venv/.

Python Versions #

COMMANDDESCRIPTION
uv python listAvailable and installed versions
uv python install 3.12Download and install a version
uv python pin 3.12Write .python-version for the project
uv venv --python 3.12Create a venv with a specific version
uv run --python 3.13 script.pyRun once with another version

Python Versions: More #

COMMANDDESCRIPTION
uv python list --only-installedOnly versions already installed (--all-versions shows every patch release)
uv python install 3.11 3.12Install several at once
uv python upgrade 3.12Upgrade a uv-managed minor version (no argument upgrades all)
uv python find '>=3.11'Show the interpreter uv would pick
uv python pin --globalSet a user-wide default version

Virtual Environments and pip Interface #

COMMANDDESCRIPTION
uv venvCreate .venv
uv venv <PATH>Create it elsewhere
source .venv/bin/activateActivate (Linux and macOS)
.venv\Scripts\Activate.ps1Activate (Windows PowerShell)
deactivateLeave the environment
uv pip install <PKG>Install into the active or .venv environment
uv pip install -r requirements.txtInstall from a file
uv pip install -e .Editable install of the current project
uv pip list, uv pip freezeWhat is installed
uv pip uninstall <PKG>Remove
uv pip compile requirements.in -o requirements.txtPin to a lock-style file
uv pip sync requirements.txtMake the environment match the file exactly

The uv pip interface is a drop-in for most pip commands; the uv add / uv sync project workflow is preferred for anything you keep.

Scripts with Inline Metadata (PEP 723) #

Dependencies live in a comment block at the top of a single file, so the script is self-contained.

python
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///
import requests
from rich import print

r = requests.get("https://api.github.com/repos/astral-sh/uv", timeout=10)
print(r.json()["stargazers_count"])
COMMANDDESCRIPTION
uv run script.pyRun; uv builds a cached throwaway environment from the metadata
uv add --script script.py <PKG>Add a dependency to the block
uv remove --script script.py <PKG>Remove one
uv lock --script script.pyLock the script’s dependencies
chmod +x script.py && ./script.pyRun directly via the shebang
uv run --with <PKG> script.pyOne-off extra dependency without editing the file
uv run --no-project script.pyIgnore the surrounding project

Tools (pipx replacement) #

COMMANDDESCRIPTION
uvx <TOOL> [ARGS]Run a tool in a temporary environment (alias of uv tool run)
uvx ruff check .Example: lint without installing
uvx --from <PKG> <CMD>When the command name differs from the package name
uvx <TOOL>@<VERSION>Run a specific version
uv tool install <TOOL>Install into an isolated environment, put it on PATH
uv tool listInstalled tools
uv tool upgrade <TOOL> / --allUpgrade
uv tool uninstall <TOOL>Remove
uv tool update-shellAdd the tool bin directory to PATH
uv tool install --with <EXTRA_PKG> <TOOL>Install a tool with an extra package in its environment (repeatable)
uv tool install --python <VERSION> <TOOL>Pick the Python version
uv tool install --force <TOOL>Overwrite an executable not installed by uv
uv tool upgrade <TOOL> --upgrade-package <PKG>Upgrade one dependency inside a tool
uv tool upgrade <TOOL> --reinstallRebuild the tool environment

uv vs pipx vs pip #

NEEDuvpipxpip
Run a CLI onceuvx <TOOL>pipx run <TOOL>n/a
Install a CLI globally, isolateduv tool installpipx installPollutes the environment
Project dependencies and lockfileuv add, uv syncn/apip install plus manual pins
Manage Python versionsuv python installn/an/a
SpeedFast (parallel, cached)Uses pip internallySlowest

Workspaces #

One lockfile for several packages in a monorepo.

toml
[project]
name = "albatross"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["bird-feeder"]

[tool.uv.sources]
bird-feeder = { workspace = true }

[tool.uv.workspace]
members = ["packages/*"]
exclude = ["packages/seeds"]
COMMANDDESCRIPTION
uv lockLocks the whole workspace at once
uv run --package <MEMBER> <CMD>Run in a member (uv sync --package works too)
uv run --all-packages <CMD>Install every member first
uv init (inside an existing package)Adds the new member to the workspace

uv run and uv sync act on the workspace root by default. Workspace dependencies are editable. A tool.uv.sources entry in the root applies to every member.

Cache #

COMMANDDESCRIPTION
uv cache dirShow the cache location
uv cache cleanRemove everything (destructive, forces re-download)
uv cache clean <PKG>Clear one package
uv cache pruneRemove unused entries
uv cache prune --ciKeep wheels built from source, drop pre-built wheels (run at the end of CI jobs)
uv sync --refreshRevalidate cached data (--refresh-package <PKG>, --reinstall, --no-cache also exist)

Environment Variables #

VARIABLEDESCRIPTION
UV_CACHE_DIRCache directory
UV_NO_CACHEDisable the cache
UV_PYTHONInterpreter to use for all operations
UV_PYTHON_PREFERENCEPrefer system or managed Python
UV_PYTHON_INSTALL_DIRWhere managed Pythons are stored
UV_PROJECT_ENVIRONMENTPath of the project virtual environment
UV_TOOL_DIR / UV_TOOL_BIN_DIRWhere tools and their executables go
UV_DEFAULT_INDEXDefault package index (UV_INDEX_URL is deprecated), UV_INDEX adds more
UV_LINK_MODEHow files are linked from the cache
UV_COMPILE_BYTECODECompile to bytecode after install
UV_FROZEN / UV_LOCKEDSame as --frozen / --locked
UV_EXCLUDE_NEWERIgnore packages published after a date (false disables)
UV_OFFLINEDisable network access
UV_SYSTEM_PYTHONUse the first Python on PATH

pyproject.toml #

toml
[project]
name = "myapp"
version = "0.1.0"
description = "Homelab helper"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
    "requests>=2.31",
    "pyyaml",
]

[project.scripts]
myapp = "myapp.cli:main"

[dependency-groups]
dev = ["pytest", "ruff"]

[tool.ruff]
line-length = 100

[project.scripts] creates a myapp command when the project is installed (uv tool install . or uv pip install -e .).

Plain venv and pip #

COMMANDDESCRIPTION
python3 -m venv .venvCreate a virtual environment
source .venv/bin/activateActivate
python -m pip install --upgrade pipUpgrade pip
pip install <PKG>Install
pip install -r requirements.txtInstall from a file
pip freeze > requirements.txtPin everything currently installed
pip list --outdatedShow available upgrades
pip show <PKG>Package details
pip uninstall <PKG>Remove
python3 -m pip --versionWhich pip and which Python
which pythonConfirm you are using the venv one

On Debian and Ubuntu, pip install outside a venv fails with externally-managed-environment (PEP 668). Use a venv, uv, or pipx instead of --break-system-packages. If python3 -m venv complains, install python3-venv.

Everyday One-Liners #

COMMANDDESCRIPTION
python3 -m http.server 8000Serve the current directory over HTTP
python3 -m json.tool < file.jsonPretty-print JSON
python3 -c 'import sys,json; print(json.load(sys.stdin)["key"])'Read a JSON field
python3 -m venv --helpVenv options
python3 -m py_compile script.pySyntax check
uv run python -m pdb script.pyDebugger

Not Checked #

uv cache size, uv tool dir, uv python dir and uv python uninstall, uv pip tree, uv version --bump, uv self version, and the --exclude-newer and index flags on uv sync and uv lock (verified on other commands only).

See Also #

Search all sheets

Tip: / or Ctrl/Cmd+K to open, Esc to close.