MLOps, Session 2: a short reminder
One fast tool, written in Rust by Astral, that replaces five older ones.
macOS and Linux
Windows (PowerShell)
Open a new terminal, then check:
brew install uvwinget install --id=astral-sh.uv -euv self updateuv add and uv run call both commands for you. Commit uv.lock: it is what makes another machine install the same versions.
uv init # new project: pyproject.toml, .python-version
uv add pandas # add a dependency, update uv.lock, install
uv add --dev pytest # development-only dependency
uv remove pandas # remove it again
uv sync # make .venv match uv.lock (after git clone)
uv lock --upgrade-package pandas # upgrade one package, leave the restuv add, never pip install into the projectgit clone, one command rebuilds the environment: uv sync[project] # what the project needs to RUN
name = "fraud-lab"
requires-python = ">=3.12"
dependencies = [
"pandas>=3.0.6",
"scikit-learn>=1.9.1",
]
[dependency-groups] # what you need to DEVELOP
dev = [
"ruff>=0.6",
{include-group = "test"}, # dev also contains test
]
test = ["pytest>=8"]
docs = ["mkdocs>=1.6"][dependency-groups] is a table: one key per groupdev = [ ... ] is a list of strings, like "pytest>=8"{include-group = "test"} nests a group: dev also installs testdev is synced by default; test and docs are names you chooseThe same flags work with uv run.
Three flags decide what happens when the lockfile is stale:
--locked: error if uv.lock is out of date, never rewrite it--frozen: use uv.lock as it is, without checking--no-sync: run without checking that .venv is up to dateuv lock --check is the same test as --locked, without running anything.
uvx ruff check .: run a tool once, in a throwaway environment (uvx = uv tool run)uv tool install ruff: keep it on your PATH, like pipxuv add --dev ruff: the project needs it, so everyone gets the same version through uv.lockRule of thumb: if the code or the CI depends on the tool, it is a dev dependency, run with uv run. Everything else is uvx.
steps:
- uses: actions/checkout@v7
- uses: astral-sh/[email protected]
with:
version: "0.13.5" # pin uv itself
enable-cache: true # reuse downloads between runs
- run: uv sync --locked # fails if uv.lock is out of date
- run: uv run pytestWith --locked, a pull request that changes pyproject.toml without updating uv.lock turns the build red.
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:0.13.5 /uv /uvx /bin/
ENV UV_LINK_MODE=copy UV_COMPILE_BYTECODE=1
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --locked --no-install-project --no-dev # dependencies layer
COPY . .
RUN uv sync --locked --no-dev # then the project
CMD ["uv", "run", "--no-sync", "python", "predict.py"]uv.lock changes.venv to .dockerignore: a laptop environment does not run in Linuxpyproject.toml and uv.lock; never .venv/uv add, not pip install--locked in CI and Docker: a stale lock fails loudlylatestuv lock --upgrade-package <name>dev group, one-off tools with uvxAlbert School, uv in practice