python-tools
Pip and PIPX
pip basics
Installing packages
Here is how to find out what versions of a package exist:
pip index versions localemu
pipx
The pipx is basically pip's npx alternative, where a virtual environment is managed for you in your home directory rather than in the CWD.
Here is how to install it:
brew install pipx
Package management
pipx install <package>: installs a packagepipx uninstall <package>: installs a package
To install packages globally with pipx, just run pipx install.
pipx install localemu
You can also specify a specific version to install with package-version syntax below:
pipx install "<package>==<version>"
pipx install "localemu==1.2.0"
NOTE
When installing Python packages, the way to refer to a specific version is through the "<package>==<version>" syntax.
Here is how to use a specific Python version to install a package:
pipx install --python /usr/bin/python3.12 "localemu==1.2.0"
UV
Installation
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Or
# Homebrew (macOS)
brew install uv
# pip (if Python is already installed)
pip install uv
Managing Python versions
uv python install <version>: installs a specific version of pythonuv python uninstall <version>: uninstalls a specific version of pythonuv python find <version>: shows the path to a specific version of pythonuv python pin <version>: Pin the current project to use a specific Python version.uv python list: View available Python versions.
# Install a specific Python version
uv python install 3.12
# List available versions
uv python list
# Install multiple versions for testing
uv python install 3.11 3.12 3.13
Virtual environments
The uv venv command creates a virtual environment in the CWD in one command
Here is how you can name your virtual environment folder:
uv venv .venv # creates a virtual environment by creating .venv folder
Package management
uv pip
If you have existing workflows built around pip and requirements files, uv provides a drop-in compatible interface:
# Install from requirements.txt
uv pip install -r requirements.txt
# Install a package
uv pip install requests
# Generate a locked requirements file from loose constraints
uv pip compile requirements.in -o requirements.txt
# Sync an environment to match a requirements file exactly
uv pip sync requirements.txt
NOTE
These commands produce identical results to their pip equivalents but run 10-100x faster. Swap pip for uv pip in your CI scripts for an immediate speed boost without changing your project structure.
uv pip install: Install packages into the current environment.uv pip show: Show details about an installed package.uv pip freeze: List installed packages and their versions.uv pip check: Check that the current environment has compatible packages.uv pip list: List installed packages.uv pip uninstall: Uninstall packages.uv pip tree: View the dependency tree for the environment.
Projects
You can initialize a project to use uv using the uv init command and specifying the project folder:
uv init <foldername>
You can then add dependencies using the uv add command:
uv add <package>
uv init scaffolds a new project with a pyproject.toml. The virtual environment and lockfile are created when you first run uv sync, uv add, or uv run.
# Create a new project
uv init my-project
cd my-project
# Add dependencies
uv add requests
uv add pandas numpy
# Add development dependencies
uv add --dev pytest ruff
# Install everything (creates/updates .venv and uv.lock)
uv sync
# Run the console script uv init created
uv run my-project
Here is the basic workflow:
-
Init a uv project in either the current directory or make a new one and select your specific python version
uv init <foldername> --python <version>
- Sync project, which initializes venv and activates it and installs all dependencies in the
pyproject.toml
uv sync
NOTE
uv.lock pins every direct and transitive dependency to an exact version, ensuring reproducible installs across machines. Unlike pip freeze output, uv’s lockfile is cross-platform by default.
Quickstart
uv init: Create a new Python project.uv add: Add a dependency to the project.uv remove: Remove a dependency from the project.uv sync: Sync the project's dependencies with the environment.uv lock: Create a lockfile for the project's dependencies.uv run: Run a command in the project environment.uv tree: View the dependency tree for the project.uv build: Build the project into distribution archives.uv publish: Publish the project to a package index.
pyproject.toml
This is what a pyproject.toml looks like:
[project]
name = "text-analyzer"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.10"
dependencies = []
[project.scripts]
text-analyzer = "text_analyzer:main"
[build-system]
requires = ["uv_build>=0.12.0,<0.13.0"]
build-backend = "uv_build"
- The
[project.scripts]line is what makestext-analyzerrunnable as a command: it points at themainfunction inside thetext_analyzermodule. - The
[build-system]table tells Python how to build the project into an installable package.
Now you can run this project as uv run text-analyzer, where text-analyzer is a custom script that just runs the main() function in the text_analyzer.py file.
Project initialization in depth
Setting a python version
You can pin a project to a specific Python version with a .python-version file:
uv python pin 3.12
This writes a .python-version file that uv (and other tools) respect. When a collaborator clones the project and runs uv sync, uv reads this file and downloads the specified interpreter if it is not already installed.
Changing your project’s Python version is straightforward:
uv python pin 3.13
uv sync
uv add
You can now add whatever dependencies with uv add and run files with uv run.
Each uv add updates pyproject.toml, refreshes uv.lock, and installs the package into .venv/.
Creating a new project will generate 1) uv.lock file in the project and 2) .venv/ directory that stores the virtual environment
.venv: The virtual environment holds the project’s Python interpreter and installed packages and records the exact version of every installed package, so everyone working on the project gets identical installs.uv.lock: The lockfile pins exact versions so anyone else can reproduce the environment with one command.
Dev dependencies
You can add dev dependencies with the --dev flag, which adds those packages into a separate [dependency-groups] table within the pyproject.toml instead of the main dependencies list.
uv add --dev pytest
They get installed in .venv/ like any other package, but uv sync --no-dev will skip them, which matters when you build a slim Docker image or deploy to production.
Use the dev tools through uv run so they pick up the project’s venv automatically. If you call ruff directly without uv run, your shell either reports command not found: ruff or runs a different Ruff installed elsewhere on your machine.
$ uv run ruff format .
$ uv run ruff check --fix .
uv run
The uv run command runs a python file, automatically creating and using a virtual environment, but can also be used npm style to run scripts.
Running files
uv run can be passed a python filepath and run that python file in the context of the current virtual environment.
uv run <filename>
Here are the additional flags you have access to:
--with <package>: specifies a package to install and run the package with.--python <version>: specifies a specific Python version to use to run the file with.
You can also pass dependencies on the command line without modifying the script:
uv run --with requests script.py
This is useful for quick experiments or when running someone else’s script with an additional package. You can even specify a Python version:
uv run --python 3.11 script.py
For interactive work, uv launches a REPL with your project’s dependencies available:
uv run python
Running scripts
uv run executes a Python script after ensuring the project’s virtual environment is up to date. For one-off scripts that aren’t part of a project and you don't want to force the script consumer to install a virtual environment just to use your CLI, you can specify dependencies inline using PEP 723 metadata:
# /// script
# dependencies = ["requests", "rich"]
# requires-python = ">=3.11"
# ///
import requests
from rich import print
response = requests.get("https://api.github.com/zen")
print(response.text)
You can then run the script with uv run <filename>:
uv run script.py
Installing and using packages globally
Many Python packages ship command-line tools: Ruff, Black, Jupyter, and dozens more. uv provides two ways to run them:
uvx: the drop-in replacement forpipx, which allows you to both run and install packages.uv tool install: installs packages globally and adds them to the path.
NOTE
Which to use maps to how often you run the tool:
uvxfor occasional or one-off runsuv tool installfor daily use with the tool on your PATH. 4
Both isolate the tool’s dependencies from your project.
uvx
uvx runs a tool in a temporary, isolated environment. No installation required. The tool is cached for fast subsequent runs:
uv tool install
uv tool install installs a tool permanently so it’s available as a regular command:
uv tool install ruff
ruff check . # now available directly
This replaces pipx for most use cases. Each tool gets its own isolated environment, so tools never conflict with each other or with your project’s dependencies.
Here is an example of installing a global package with a specific version and specific python interpreter version.
uv tool install --python 3.12 "localemu==1.2.0"
You can also upgrade installed tools:
uv tool upgrade ruff
uv tool upgrade --all
Here is a list of all uv tool commands:
uv tool install <package>: Install a tool user-wide.uv tool uninstall <package>: Uninstall a tool.uv tool list: List installed tools.uv tool upgrade <package>: Upgrade a specific package
uv format
uv includes a uv format command that formats Python code using Ruff’s formatter.
# Format all Python files in the project
uv format
# Check formatting without making changes
uv format --check
Formatting settings are read from [tool.ruff.format] in your pyproject.toml. If you already use Ruff for formatting, uv format uses the same configuration.
NOTE
uv format is experimental and prints a preview warning. Its interface may change. For a stable formatting setup today, run Ruff directly (uvx ruff format) or pin a uv version in CI.
uv with pytest
uv add --dev pytest
uv run pytest
Ruff
Ruff gives Python developers a single tool for linting, formatting, import sorting, and code modernization.
One dev dependency, one configuration section in pyproject.toml, one CI step. It ships as a standalone binary with no runtime dependencies, so installation is fast and there are no version conflicts to manage.
Installation
The recommended way to add Ruff to a project is as a dev dependency:
uv add --dev ruff
For one-off usage without installing:
uvx ruff check .
For a global install available on your PATH:
uv tool install ruff
Alternative methods:
pip install ruff
pipx install ruff
Confirm the installation:
ruff --version
ruff check
ruff check scans Python files for errors, style violations, and potential bugs:
# Check all files in the current directory
ruff check .
# Check a specific file
ruff check src/main.py
# Check a specific directory
ruff check src/
Output shows the file, line, column, rule code, and message:
src/main.py:3:1: F401 [*] `os` imported but unused
src/main.py:7:5: F841 Local variable `x` is assigned to but never used
The [*] marker indicates a rule with an available auto-fix. Apply all safe fixes with:
ruff check --fix .