dylan@kernellab:~/articles/en/devops$cat python_uv.md
devops ~20 min read

Discovering UV: The Ultra-Fast Python Package & Project Manager

Discover UV, an extremely fast Python package and project manager designed to replace pip, virtualenv, and poetry. Explore key features, installation, and real-world examples.

Published
#python#uv#pip#virtualenv#astral#devops
Discovering UV: The Ultra-Fast Python Package & Project Manager

Discovering UV: The Ultra-Fast Python Package & Project Manager

UV is an exceptionally fast Python package and environment manager built by Astral (the team behind the popular Ruff linter and formatter). Written in Rust, it is designed to unify and replace legacy tools such as pip, pip-tools, virtualenv, poetry, and pyenv.

Traditionally, the standard Python workflow required multiple manual, disjointed steps:

  1. Create a virtual environment: python -m venv .venv
  2. Activate it: source .venv/bin/activate (or .venv\Scripts\activate on Windows)
  3. Install dependencies: pip install <package>
  4. Pin versions: pip freeze > requirements.txt

In 2026, those days are over: UV brings all of this into a single, unified tool, slashing execution times by 10x to 100x thanks to its Rust-powered resolution engine and global caching strategy.

Unlike pip, UV resolves dependency graphs concurrently and caches packages (wheels) at the OS level. If a package has already been downloaded for one project, it is instantly linked to other projects using filesystem hardlinks—avoiding duplicate disk usage and redundant network downloads.

1. Installation

You can install UV with a single command using Astral's official installer:

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

You can also install it via Homebrew on macOS:

brew install uv

Updating UV

UV comes with a built-in self-update command:

uv self update

2. Quickstart: Your Project in 30 Seconds

UV modernizes your development workflow using current standards (PEP 621 compliant pyproject.toml).

Initialize a project

# Creates a new directory and scaffolds the project structure
uv init mon-api
cd mon-api

This command automatically generates:

  • pyproject.toml: The standard project configuration file.
  • .python-version: Pins the target Python version.
  • src/__init__.py: A ready-to-run starter structure.

Adding and removing dependencies

When adding a dependency, UV takes care of everything: automatically creating the .venv directory, resolving dependencies, updating pyproject.toml, and generating a lockfile (uv.lock).

# Add main dependencies
uv add fastapi uvicorn

# Remove a dependency
uv remove uvicorn

# Upgrade all dependencies according to constraints
uv lock --upgrade

Running code without activating the virtual environment

This is one of UV's biggest quality-of-life improvements: you no longer need to manually activate the virtual environment with source .venv/bin/activate.

# Directly run a package entrypoint or script in the virtual environment
uv run mon-api

# Start a development server
uv run uvicorn main:app --reload

The uv run workflow

uv run inspects your project, ensures .venv is in sync with uv.lock (updating it on the fly if needed), and executes the command within the correct context. It is ideal for local scripts, cron jobs, and CI/CD pipelines!


3. On-Demand Python Version Management

No need to install and configure pyenv just to switch Python versions: UV manages downloading and isolating Python runtimes automatically.

# List available Python runtimes
uv python list

# Install a specific version (e.g., Python 3.12 or 3.13)
uv python install 3.12

# Pin the runtime version for the current project
uv python pin 3.12

4. Organizing Dependencies with Groups

In production projects, development tooling (test frameworks, linters, documentation generators) must not end up in your production build. UV lets you organize dependencies into isolated groups using the --group flag:

# Development & linting tools
uv add ruff mypy --group dev

# Unit testing tools
uv add pytest pytest-asyncio httpx --group test

Your pyproject.toml remains clean and standardized:

[project]
name = "mon-api"
version = "0.1.0"
description = "FastAPI application with UV"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    "fastapi>=0.115.0",
    "uvicorn>=0.30.0",
]

[dependency-groups]
dev = [
    "mypy>=1.11.0",
    "ruff>=0.6.0",
]
test = [
    "httpx>=0.27.0",
    "pytest>=8.3.0",
    "pytest-asyncio>=0.24.0",
]

To synchronize an environment by installing or omitting specific groups:

# Install production dependencies only (ideal for Docker images)
uv sync --no-dev

# Synchronize including a specific group
uv sync --group test

5. Enterprise Setup: Proxies and Private Registries

In enterprise environments, egress traffic is often proxied and packages are hosted on private registries (Nexus, Artifactory, AWS CodeArtifact, Google Artifact Registry).

Configuring an HTTP/HTTPS Proxy

Instead of manually exporting shell variables on every developer machine, you can define your corporate proxy directly inside pyproject.toml or uv.toml:

[tool.uv]
http-proxy = "http://proxy.enterprise.internal:8080"
https-proxy = "http://proxy.enterprise.internal:8080"

Using a Private Package Registry

To consume internal proprietary packages from AWS CodeArtifact, Google Cloud Artifact Registry, or GitLab Package Registry:

[[tool.uv.index]]
name = "private-registry"
url = "https://europe-west1-python.pkg.dev/my-gcp-project/pypi/simple/"
default = false
# Install an internal package from your private registry
uv add internal-sdk --index private-registry
For private repository authentication, UV natively reads standard environment variables such as UV_INDEX_<NAME>_PASSWORD or UV_INDEX_URL so you never commit credentials to Git.

6. Advanced Use Cases and Concrete Examples

A. Standalone Scripts with Inline Metadata (PEP 723)

Need to share a quick automation script without creating an entire project repository? UV can execute standalone scripts with self-declared dependencies right at the top of the file:

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "requests",
#     "rich",
# ]
# ///

import requests
from rich.console import Console

console = Console()
response = requests.get("https://api.github.com/repos/astral-sh/uv")
stars = response.json().get("stargazers_count", 0)

console.print(f"[bold green]GitHub Stars for UV:[/bold green] [yellow]{stars}[/yellow]")

Run this script directly:

uv run stats.py

UV creates an isolated ephemeral environment, runs the script, and caches dependencies without altering your global Python setup.

B. Ultra-Fast Multi-Stage Dockerfile

In CI/CD pipelines and containerized deployments, UV drastically cuts build times thanks to its small binary footprint and the official base images provided by Astral:

# Step 1: Build & dependency resolution
FROM python:3.12-slim AS builder

# Copy UV binary from the official Astral image
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv

WORKDIR /app

# Optimize Docker layer caching: copy dependency manifests first
COPY pyproject.toml uv.lock ./

# Synchronize virtualenv without dev packages
RUN uv sync --frozen --no-dev --no-install-project

# Step 2: Minimal runtime image
FROM python:3.12-slim AS runner

WORKDIR /app

# Copy pre-built virtual environment
COPY --from=builder /app/.venv /app/.venv
COPY . .

ENV PATH="/app/.venv/bin:$PATH"

EXPOSE 8000
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

C. Serverless Deployment (AWS Lambda / Cloud Functions)

For deploying FastAPI applications to AWS Lambda with an ASGI adapter like Mangum, pairing it with UV streamlines packaging:

uv add fastapi mangum
# app.py
from fastapi import FastAPI
from mangum import Mangum

app = FastAPI(title="Lambda API with UV")

@app.get("/")
def home():
    return {"status": "running", "runtime": "AWS Lambda"}

# AWS Lambda Handler
handler = Mangum(app)

With uv export --format requirements-txt > requirements.txt, you can export locked dependencies in milliseconds to build your Lambda layer or container image.


Essential Commands Cheat Sheet

ActionUV CommandLegacy Equivalent
Initialize a projectuv initmkdir && git init && poetry new
Add a packageuv add <package>pip install <package> && pip freeze
Add a dev dependencyuv add <package> --group devpoetry add -D <package>
Run a scriptuv run <script.py>source .venv/bin/activate && python ...
Install Pythonuv python install 3.12pyenv install 3.12
Sync environmentuv syncpip install -r requirements.txt
Clean cacheuv cache cleanpip cache purge

Official Resources

To learn more about workspace management, wheel compilation, and CI/CD actions (GitHub Actions, GitLab CI), check out the official UV documentation.