# pipx: Isolated Python CLI Tools Without the Mess

LLMS index: [llms.txt](/en/llms.txt)

---

pipx solves a simple but chronic problem: you need to run a Python utility once or occasionally, and `pip install` pollutes the global environment or leaves behind a virtual environment you forget to clean up. pipx creates an isolated venv for each utility, installs dependencies there, and makes the binary available in `$PATH`. One command and the tool works without conflicting with anything.

## What Is pipx and Why You Need It

pipx installs and runs Python applications in isolated virtual environments. Each utility lives in its own venv under `~/.local/pipx/venvs/`, and its console-scripts are symlinked into `~/.local/bin/`.

Problems it solves:

- Version conflicts between projects: `black==23` and `black==24` can't coexist in one environment, but in pipx they can.
- Global `pip install` pollutes system Python and can break `apt` on Debian-based systems.
- Forgotten venvs after one-off usage.

> [!NOTE]
> pipx doesn't replace `pip` inside projects. It's a tool for CLI utilities: `black`, `poetry`, `httpie`, `ansible`, `awscli`, `pre-commit`, and similar.

## Installing pipx

The most reliable path is through `pip` in user mode or through your system package manager.

```bash
# Option 1: via pip (Python 3.6+)
python3 -m pip install --user pipx
python3 -m pipx ensurepath

# Option 2: via apt (Debian/Ubuntu; version may be older)
sudo apt install pipx

# Option 3: via brew (macOS)
brew install pipx
```

After installation, verify `~/.local/bin` is in `$PATH`:

```bash
echo $PATH | grep -q "$HOME/.local/bin" && echo "OK" || echo "add to PATH"
```

> [!WARNING]
> If `ensurepath` didn't work, add it manually to `~/.bashrc` or `~/.zshrc`:
> `export PATH="$HOME/.local/bin:$PATH"`

## Basic Commands: install, run, list

Three commands cover 90% of use cases.

```bash
# Install a utility globally (creates venv, symlinks binary)
pipx install black

# Run a utility without installing it (download + run in a temporary venv)
pipx run httpie https://api.example.com/health

# List all installed utilities
pipx list
```

Flags worth remembering:

| Flag | What it does | Example |
|------|-------------|---------|
| `--spec` | Specify source (PyPI, git, wheel) | `pipx install --spec git+https://github.com/user/repo.git tool` |
| `--suffix` | Add suffix to binary name | `pipx install black --suffix==24` |
| `--python` | Specify interpreter | `pipx install --python python3.11 black` |
| `--system-site-packages` | Enable access to system packages | `pipx install --system-site-packages tool` |
| `--force` | Reinstall over existing | `pipx install --force black` |

> [!TIP]
> `pipx run` is the key command for one-off usage. It downloads the package, creates a temporary venv, executes, and removes it. No trace left behind.

## Managing Dependencies and Reinstallation

After installation you can upgrade, remove, and inspect dependencies.

```bash
# Upgrade a single utility
pipx upgrade black

# Upgrade all installed utilities
pipx upgrade-all

# Remove a utility and its venv entirely
pipx uninstall black

# Remove everything except pipx itself
pipx uninstall-all

# Inspect dependencies of an installed package
pipx list --verbose
```

If something breaks, reinstallation takes seconds:

```bash
pipx reinstall black
# or with a specific interpreter
pipx reinstall --python python3.12 black
```

> [!WARNING]
> `pipx upgrade-all` can bump a tool to a version with breaking changes. In CI/CD, pin the version instead: `pipx install black==24.8.1`.

## Typical DevOps Scenarios

pipx fits several working patterns where a full project with `requirements.txt` is overkill.

**1. One-off utilities in CI/CD.** Instead of installing into a Docker image or globally:

```bash
# In a Dockerfile or entrypoint script
pipx run --spec https://pypi.org/project/aws-nuke/ aws-nuke --force --account-id $AWS_ACCOUNT_ID
```

**2. Parallel versions of the same tool.** Useful during project migrations:

```bash
pipx install black --suffix==23
pipx install black --suffix==24
black==23 --version
black==24 --version
```

**3. Local dev environment without privileges.** Install `ansible`, `pre-commit`, and similar tools without `sudo` and without affecting system Python.

**4. Quick package evaluation before integration.** Test a utility without adding it to `requirements.txt`:

```bash
pipx run httpx https://example.com
# If it works — install permanently
pipx install httpx
```

> [!TIP]
> Combined with `direnv` and `.envrc`, you can wire up `pipx run` for project-specific tasks — the utility is available only in that directory, and dependencies don't leak into the global environment.

pipx doesn't try to be a package manager for all of Python. It does one thing — isolated CLI utility installation — and does it without the noise. For a Lead DevOps, that means less time fighting dependency conflicts and more time on architecture.
