Python pipx

ID

pipx

Home page

https://pipx.pypa.io

Version requirement

>= 1

Cooldown

Platforms

🅱️ BSD · 🐧 Linux · 🍎 macOS · ⨂ Unix · 🪟 Windows

Operations

installed · outdated · install · upgrade · upgrade_all · remove

purl types

pkg:pipx · pkg:pypi

CLI name

pipx

Issues and PRs

📦 manager: pypi-based

Source

meta_package_manager/managers/pipx.py

pipx installs Python CLI applications, each in its own isolated venv.

Installed applications come from pipx list --json; only each venv’s main package is tracked, never the packages injected beside it. There is no search operation: the request was closed as not planned, since PyPI exposes no search API and custom search is out of pipx’s scope (see pypa/pipx#777).

Note

The outdated query prefers pipx 1.16.0’s native pipx list --outdated, which checks every venv in one call, each against its own backend (pip or uv). An older pipx falls back to probing each venv with its embedded pip, one call per application. The version floor stays at 1.0.0 so an older pipx remains fully usable: only the outdated path degrades.

Note

The supply-chain cooldown rides on the underlying pip and needs that pip to be at least 26.1, the first release to honor --uploaded-prior-to; older pip silently ignores the release-age gate.

What mpm adds to pipx

mpm reaches across every manager at once, not pipx alone: mpm installed and mpm outdated cover pipx alongside pip, uv and any other manager you run in one table, mpm upgrade --all updates them together, and mpm sbom exports the whole machine as one bill of materials.

Every mpm command also gains --dry-run and --plan previews, cross-scheme version comparison and purl identifiers. See manager augmentations for how each one is built.

Your pipx commands, in mpm

You already know pipx: each operation maps one-to-one onto mpm, in an interface shared by every manager.

To…

With pipx

With mpm

List what’s installed

pipx list --json

mpm --pipx installed

List outdated packages

pipx list --outdated --output=json

mpm --pipx outdated

Install a package

pipx install pycowsay

mpm install pkg:pipx/pycowsay

Remove a package

pipx uninstall pycowsay

mpm remove pkg:pipx/pycowsay

Prefix any command above with --dry-run to simulate the underlying manager calls without touching the system: the safe way to watch what mpm would do before trusting it.

Operations

Operation

Supported

installed

outdated

orphans

search

install

upgrade

upgrade_all

remove

sync

cleanup

doctor

Selecting and configuring pipx

Deselect pipx for a single run with --no-pipx, or persist the choice in your configuration:

[mpm]
pipx = false

Keep it enabled but tune how mpm drives it with a per-manager override:

[mpm.managers.pipx]
timeout = 900

mpm config-template pipx prints every overridable attribute as a ready-to-paste block.

Recipes

A few jobs you would otherwise script around pipx, one mpm command each:

  • Snapshot and clone a machine: mpm --pipx dump pipx.toml, then mpm restore pipx.toml on the next one.

  • Export a compliance SBOM: mpm --pipx sbom (CycloneDX by default, --spdx for SPDX).

Privilege escalation

mpm runs this manager as the current user and never prepends sudo by default. Flip the policy for its privileged operations with --sudo or the per-manager sudo override.

See privilege escalation for the full policy.

Cooldown

mpm natively enforces its release-age cooldown on Python pipx, injecting the PIP_UPLOADED_PRIOR_TO environment variable on every call. Point it at a window (mpm --cooldown 7 --pipx upgrade --all) to skip anything published in the last 7 days: a guard against a compromised or yanked fresh release landing before anyone notices.

  • Status: ✅ Enforced (via pip’s env var; needs the underlying pip ≥ 26.1)

  • Mechanism: inherits PIP_UPLOADED_PRIOR_TO

  • Reference: pypa/pipx#1811

A cooldown only pays off where a compromised release can be withdrawn while the clock runs, and can only be emulated where the registry dates its releases. From the retraction table:

  • Registry: PyPI (pkg:pypi)

  • Retraction: Yank (PEP 592): the file stays downloadable, but an installer “MUST ignore yanked releases, if the selection constraints can be satisfied with a non-yanked version”

  • Publish date: ✅ upload_time_iso_8601, plus a per-file yanked flag (JSON API)

Version probe

The version is extracted from the output of pipx --version with:

r"(?P<version>\S+)"

Reference traces

Raw native outputs captured in the manager source: the reference mpm’s parsers were written against. If you know Python pipx well and a transcript below looks wrong, or a newer release changed its output format, report it.

$ pipx list --json
{
  "pipx_spec_version": "0.1",
  "venvs": {
      "pycowsay": {
        "metadata": {
          "injected_packages": {},
          "main_package": {
            "app_paths": [
              {
                "__Path__": "~/.local/pipx/venvs/pycowsay/bin/pycowsay",
                "__type__": "Path"
              }
            ],
            "app_paths_of_dependencies": {},
            "apps": [
              "pycowsay"
            ],
            "apps_of_dependencies": [],
            "include_apps": true,
            "include_dependencies": false,
            "package": "pycowsay",
            "package_or_url": "pycowsay",
            "package_version": "0.0.0.1",
            "pip_args": [],
            "suffix": ""
          },
        "pipx_metadata_version": "0.2",
        "python_version": "Python 3.10.4",
        "venv_args": []
      }
    }
  }
}
$ pipx list --outdated --output=json
{
  "command": ["list"],
  "data": {
    "packages_checked": 1,
    "packages": [
      {
        "environment": "pycowsay",
        "package": "pycowsay",
        "version": "0.0.0.1",
        "latest_version": "0.0.0.2",
        "injected": false,
        "pinned": false
      }
    ],
    "skipped": []
  },
  "errors": [],
  "exit_code": 0,
  "pipx_result_version": "1",
  "status": "success"
}
$ pipx runpip pycowsay list --no-color --format=json --outdated         > --verbose --quiet
[
  {
    "name": "pycowsay",
    "version": "0.0.0.1",
    "location": "~/.local/pipx/venvs/pycowsay/lib/python3.10/site-packages",
    "installer": "pip",
    "latest_version": "0.0.0.2",
    "latest_filetype": "wheel"
  }
]

Feed any of these through mpm and the raw output becomes one uniform table, the same shape for every manager: filter it, project columns, or export it (mpm --pipx installed --output json, or csv, toml, yaml), each package carrying a purl and a version comparable across managers.

Changelog

  • 7.3.0 (2026-07-17)

    • outdated now relies on pipx’s native pipx list --outdated query on pipx 1.16.0 and newer: all venvs are checked in a single call, each by its own backend (pip or uv). Older pipx keeps the previous per-venv pip probes.

  • 5.4.0 (2022-06-29)

    • Implement outdated operation.

  • 5.2.0 (2022-06-16)

    • Add remove operation.

  • 5.1.0 (2022-05-15)

    • Add pipx support. Closes #468.