Skip to main content

 

Comprehensive UV Tutorial for Python

Table of Contents

  1. Introduction
  2. Installation
  3. Basic Concepts
  4. Project Management
  5. Working with Dependencies
  6. Python Version Management
  7. Script Management
  8. Tool Management
  9. Virtual Environments
  10. The pip Interface
  11. Building and Publishing
  12. Advanced Features
  13. Migration Guide
  14. Best Practices

Introduction

UV is an extremely fast Python package and project manager written in Rust that aims to replace multiple tools in the Python ecosystem. It combines the functionality of pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more into a single, fast tool.

Key Features

  • 🚀 Single tool replacement for multiple Python package management tools
  • ⚡️ 10-100x faster than pip
  • 🗂️ Comprehensive project management with universal lockfiles
  • ❇️ Script execution with inline dependency metadata
  • 🐍 Python version management
  • 🛠️ Tool installation and execution
  • 🔩 pip-compatible interface for easy migration
  • 🏢 Cargo-style workspaces for scalable projects
  • 💾 Disk-space efficient with global caching

Installation

Standalone Installer (Recommended)

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

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

Alternative Installation Methods

# Using pip
pip install uv

# Using Homebrew (macOS)
brew install uv

# Using conda
conda install -c conda-forge uv

Verify Installation

uv --version

Basic Concepts

Core Components

  • Projects: Python applications or libraries with dependencies
  • Scripts: Single-file Python scripts with inline dependencies
  • Tools: Command-line tools installed from Python packages
  • Virtual Environments: Isolated Python environments
  • Lockfiles: Files that pin exact dependency versions

Configuration

UV uses configuration files and environment variables:

  • pyproject.toml: Project configuration
  • uv.lock: Lockfile with exact dependency versions
  • .python-version: Python version specification
  • Environment variables prefixed with UV_

Project Management

Creating New Projects

Basic Project

# Initialize in current directory
uv init

# Initialize named project
uv init myproject
cd myproject

Application Project

# For CLI apps, web applications, etc.
uv init --app --package myapp

Library Project

# For code meant to be imported
uv init --lib --package mylib

Specify Python Version

uv init --python 3.11 myproject

Project Structure

myproject/
├── pyproject.toml    # Project configuration
├── uv.lock          # Lockfile
├── README.md         # Project documentation
├── src/              # Source code
│   └── myproject/
│       └── __init__.py
└── .venv/            # Virtual environment (created when needed)

Basic Project Workflow

# 1. Initialize project
uv init myproject && cd myproject

# 2. Add dependencies
uv add requests pandas

# 3. Add development dependencies
uv add --dev pytest black ruff

# 4. Run your application
uv run python -m myproject

# 5. Run development tools
uv run pytest
uv run black .
uv run ruff check

Working with Dependencies

Adding Dependencies

Basic Dependencies

# Add single dependency
uv add requests

# Add multiple dependencies
uv add requests pandas numpy

# Add from requirements file
uv add -r requirements.txt

Development Dependencies

# Add development-only dependencies
uv add --dev pytest black ruff mypy

# Add with specific version constraints
uv add "django>=4.0,<5.0"
uv add "numpy==1.24.0"

Optional Dependencies

# Add optional dependency groups
uv add --optional web fastapi uvicorn
uv add --optional dev pytest black

# Install with optional dependencies
uv sync --extra web
uv sync --all-extras

Removing Dependencies

# Remove single dependency
uv remove requests

# Remove multiple dependencies
uv remove requests pandas numpy

# Remove development dependencies
uv remove --dev pytest

Viewing Dependencies

# Show dependency tree
uv tree

# Show specific package info
uv tree requests

# List all dependencies
uv pip list

Upgrading Dependencies

# Upgrade all dependencies
uv lock --upgrade

# Upgrade specific packages
uv add requests --upgrade

# Sync with upgraded lockfile
uv sync

Python Version Management

Installing Python Versions

# Install specific versions
uv python install 3.10 3.11 3.12

# Install latest version
uv python install 3.12

# Install preview/beta versions
uv python install 3.13t  # Free-threaded build

Managing Python Versions

# List available versions
uv python list

# List only installed versions
uv python list --only-installed

# Uninstall Python version
uv python uninstall 3.10

Using Specific Python Versions

# Pin Python version for project
uv python pin 3.11

# Pin globally
uv python pin 3.11 --global

# Run with specific Python version
uv run --python 3.11 python script.py

# Create venv with specific Python
uv venv --python 3.11

Script Management

Creating Scripts

# Initialize a new script
uv init --script myscript.py

# With specific Python version
uv init --script myscript.py --python 3.11

Example Script with Dependencies

Create example.py:

#!/usr/bin/env python
# /// script
# dependencies = [
#     "requests",
#     "click",
# ]
# ///

import requests
import click

@click.command()
@click.option("--url", default="https://httpbin.org/json")
def main(url):
    response = requests.get(url)
    click.echo(f"Status: {response.status_code}")
    click.echo(f"Data: {response.json()}")

if __name__ == "__main__":
    main()

Managing Script Dependencies

# Add dependency to script
uv add --script myscript.py requests

# Remove dependency from script
uv remove --script myscript.py requests

# Run script
uv run myscript.py

# Run with additional dependencies
uv run --with click myscript.py

# Run with specific Python version
uv run --python 3.11 myscript.py

Tool Management

Running Tools (uvx)

# Run tool in ephemeral environment
uvx pycowsay "Hello World!"

# Equivalent to:
uv tool run pycowsay "Hello World!"

# Run tool from specific package
uvx --from textual textual-demo

# Run with additional dependencies
uvx --with matplotlib --with pandas data-analysis-tool

Installing Tools

# Install tool globally
uv tool install ruff
uv tool install black
uv tool install mypy

# Install with extra dependencies
uv tool install --with ruff-lsp ruff

# Install from current project (editable)
uv tool install -e .

Managing Installed Tools

# List installed tools
uv tool list

# Upgrade specific tool
uv tool upgrade ruff

# Upgrade all tools
uv tool upgrade --all

# Uninstall tool
uv tool uninstall ruff

Virtual Environments

Creating Virtual Environments

# Create in current directory (.venv)
uv venv

# Create with custom path
uv venv path/to/my-env

# Create with specific Python version
uv venv --python 3.11

# Create with custom name
uv venv my-project-env

Using Virtual Environments

# Activate (traditional way)
source .venv/bin/activate  # Unix
# or
.venv\Scripts\activate     # Windows

# Using uv run (recommended)
uv run python script.py
uv run pytest

The pip Interface

UV provides a drop-in replacement for pip commands with enhanced performance.

Basic pip Commands

# Install packages
uv pip install requests pandas

# Install from requirements file
uv pip install -r requirements.txt

# List installed packages
uv pip list

# Show package information
uv pip show requests

# Uninstall packages
uv pip uninstall requests

Advanced pip Features

# Compile requirements
uv pip compile requirements.in -o requirements.txt

# Compile for multiple platforms
uv pip compile requirements.in --universal -o requirements.txt

# Sync environment with requirements
uv pip sync requirements.txt

# Generate requirements from current environment
uv pip freeze > requirements.txt

Building and Publishing

Building Projects

# Build distribution packages
uv build

# Build specific formats
uv build --sdist        # Source distribution only
uv build --wheel        # Wheel only

# Build to custom directory
uv build --out-dir dist/

Publishing Projects

# Publish to PyPI
uv publish

# Publish to test PyPI
uv publish --publish-url https://test.pypi.org/legacy/

# Publish with specific token
uv publish --token $PYPI_TOKEN

# Publish specific files
uv publish dist/*.whl

Version Management

# Check current version
uv version

# Bump version
uv version --bump patch    # 1.0.0 -> 1.0.1
uv version --bump minor    # 1.0.1 -> 1.1.0
uv version --bump major    # 1.1.0 -> 2.0.0

# Pre-release versions
uv version --bump minor --bump beta  # 1.0.0 -> 1.1.0b1
uv version --bump rc                 # 1.1.0b1 -> 1.1.0rc1
uv version --bump stable            # 1.1.0rc1 -> 1.1.0

Advanced Features

Workspaces

For managing multiple related projects:

Create pyproject.toml with workspace configuration:

[tool.uv.workspace]
members = ["packages/*", "apps/*"]
exclude = ["packages/legacy"]

Dependency Overrides

Override dependency versions across your project:

[tool.uv]
override-dependencies = [
    "numpy==1.24.0",  # Force specific version
]

Platform-Specific Dependencies

[project]
dependencies = [
    "requests",
    "pywin32; platform_system == 'Windows'",
    "uvloop; platform_system != 'Windows'",
]

Custom Index URLs

# Use custom package index
uv add --index-url https://my-index.com/simple/ my-package

# Add extra index
uv add --extra-index-url https://my-index.com/simple/ my-package

Configuration Files

Create uv.toml or add to pyproject.toml:

[tool.uv]
# Custom index URLs
index-url = "https://pypi.org/simple/"
extra-index-url = ["https://my-index.com/simple/"]

# Dependency resolution strategy
resolution = "highest"  # or "lowest-direct"

# Pre-release handling
prerelease = "allow"  # or "disallow", "if-necessary"

# Cache directory
cache-dir = "~/.cache/uv"

Migration Guide

From pip + virtualenv

# Old way
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# New way
uv venv
uv pip install -r requirements.txt
# or better:
uv add -r requirements.txt

From Poetry

# Convert poetry project
# 1. Keep pyproject.toml (uv will read [tool.poetry] sections)
# 2. Generate lockfile
uv lock

# 3. Install dependencies
uv sync

# 4. Remove poetry.lock if desired
rm poetry.lock

From pipenv

# Convert Pipfile to requirements
pipenv requirements > requirements.txt

# Initialize uv project
uv init

# Add dependencies
uv add -r requirements.txt

Best Practices

Project Organization

  1. Always use uv init to start new projects
  2. Commit uv.lock to version control for reproducible builds
  3. Use --dev flag for development dependencies
  4. Pin Python version with uv python pin

Dependency Management

  1. Use version constraints appropriately (be neither too loose nor too strict)
  2. Regular updates: Run uv lock --upgrade periodically
  3. Use optional dependencies for feature groups
  4. Prefer uv add over editing pyproject.toml manually

Performance Tips

  1. Use global cache: UV automatically caches packages globally
  2. Leverage lockfiles: They speed up subsequent installs
  3. Use uv run instead of activating virtual environments
  4. Install tools globally with uv tool install instead of in each project

Development Workflow

# Daily workflow
uv run pytest                    # Run tests
uv run ruff check               # Lint code
uv run ruff format              # Format code
uv run mypy .                   # Type check

# Adding new features
uv add new-dependency           # Add runtime dependency
uv add --dev new-dev-tool       # Add development tool
uv lock                         # Update lockfile

CI/CD Integration

# GitHub Actions example
- name: Install uv
  uses: astral-sh/setup-uv@v1

- name: Install Python
  run: uv python install 3.11

- name: Install dependencies
  run: uv sync --all-extras

- name: Run tests
  run: uv run pytest

Error Handling

# Common issues and solutions

# Clear cache if corrupted
uv cache clean

# Force reinstall
uv sync --refresh

# Debug resolution issues
uv tree --verbose

# Check for conflicts
uv add package --dry-run

Note: This comprehensive tutorial covers all major aspects of UV. The tool is actively developed, so always refer to the official documentation for the latest features and changes.

Comments

Popular posts from this blog

Introducing Scraperr: A Self-Hosted Web Scraping Powerhouse

In the realm of web scraping, tools that combine power, flexibility, and user-friendliness are rare. Enter Scraperr —an open-source, self-hosted web scraping solution that empowers users to extract data from websites without writing a single line of code. 🧰 What is Scraperr? Scraperr is a self-hosted web application designed to simplify the process of web scraping. It allows users to scrape websites by specifying elements via XPath, manage multiple scraping jobs, and export results in various formats—all through an intuitive interface ✨ Key Features XPath-Based Extraction : Precisely target page elements using XPath selectors. Queue Management : Submit and manage multiple scraping jobs efficiently. Domain Spidering : Option to scrape all pages within the same domain. Custom Headers : Add JSON headers to your scraping requests. Media Downloads : Automatically download images, videos, and other media. Results Visualization : View scraped data in a structured tabl...