# Inspiration | Tool | Date added | Version | | ------------------------------------------------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | [`pipx run`](https://pipx.pypa.io/latest/docs/#pipx-run) | [2019-01-27](https://github.com/pypa/pipx/releases/tag/0.11.0.0) | [0.11.0.0](https://pipx.pypa.io/latest/changelog/#:~:text=Replace%20pipx%20BINARY%20with%20pipx%20run%20BINARY) | | [`uv tool`](https://docs.astral.sh/uv/reference/cli/#uv-tool) | [2024-08-24](https://astral.sh/blog/uv-unified-python-packaging) | [0.3](https://astral.sh/blog/uv-unified-python-packaging) | ## pipx ``` usage: pipx run [-h] [--quiet] [--verbose] [--global] [--no-cache] [--path] [--pypackages] [--spec SPEC] [--python PYTHON] [--fetch-missing-python] [--system-site-packages] [--index-url INDEX_URL] [--editable] [--pip-args PIP_ARGS] app ... Download the latest version of a package to a temporary virtual environment, then run an app from it. The environment will be cached and re-used for up to 14 days. This means subsequent calls to 'run' for the same package will be faster since they can reuse the cached Virtual Environment. In support of PEP 582 'run' will use apps found in a local __pypackages__ directory, if present. Please note that this behavior is experimental, and acts as a companion tool to pythonloc. It may be modified or removed in the future. See https://github.com/cs01/pythonloc. positional arguments: app ... app/package name and any arguments to be passed to it options: -h, --help show this help message and exit --quiet, -q Give less output. May be used multiple times corresponding to the ERROR and CRITICAL logging levels. The count maxes out at 2. --verbose, -v Give more output. May be used multiple times corresponding to the INFO, DEBUG and NOTSET logging levels. The count maxes out at 3. --global Perform action globally for all users. --no-cache Do not reuse cached virtual environment if it exists --path Interpret app name as a local path --pypackages Require app to be run from local __pypackages__ directory --spec SPEC The package name or specific installation source passed to pip. Runs `pip install -U SPEC`. For example `--spec mypackage==2.0.0` or `--spec git+https://github.com/user/repo.git@branch` --python PYTHON Python to install with. Possible values can be the executable name (python3.11), the version of an available system Python or to pass to py launcher (3.11), or the full path to the executable. Requires Python 3.9 or above. --fetch-missing-python Whether to fetch a standalone python build from GitHub if the specified python version is not found locally on the system. --system-site-packages Give the virtual environment access to the system site-packages dir. --index-url, -i INDEX_URL Base URL of Python Package Index --editable, -e Install a project in editable mode --pip-args PIP_ARGS Arbitrary pip arguments to pass directly to pip install/upgrade commands ``` ## uv ``` Run a command provided by a Python package Usage: uv tool run [OPTIONS] [COMMAND] Options: --from <FROM> Use the given package to provide the command -w, --with <WITH> Run with the given packages installed --with-editable <WITH_EDITABLE> Run with the given packages installed in editable mode --with-requirements <WITH_REQUIREMENTS> Run with the packages listed in the given files -c, --constraints <CONSTRAINTS> Constrain versions using the given requirements files [env: UV_CONSTRAINT=] -b, --build-constraints <BUILD_CONSTRAINTS> Constrain build dependencies using the given requirements files when building source distributions [env: UV_BUILD_CONSTRAINT=] --overrides <OVERRIDES> Override versions using the given requirements files [env: UV_OVERRIDE=] --isolated Run the tool in an isolated virtual environment, ignoring any already-installed tools [env: UV_ISOLATED=] --env-file <ENV_FILE> Load environment variables from a `.env` file [env: UV_ENV_FILE=] --no-env-file Avoid reading environment variables from a `.env` file [env: UV_NO_ENV_FILE=] --lfs Whether to use Git LFS when adding a dependency from Git --python-platform <PYTHON_PLATFORM> The platform for which requirements should be installed [possible values: windows, linux, macos, x86_64-pc-windows-msvc, aarch64-pc-windows-msvc, i686-pc-windows-msvc, x86_64-unknown-linux-gnu, aarch64-apple-darwin, x86_64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-musl, x86_64-unknown-linux-musl, riscv64-unknown-linux, x86_64-manylinux2014, x86_64-manylinux_2_17, x86_64-manylinux_2_28, x86_64-manylinux_2_31, x86_64-manylinux_2_32, x86_64-manylinux_2_33, x86_64-manylinux_2_34, x86_64-manylinux_2_35, x86_64-manylinux_2_36, x86_64-manylinux_2_37, x86_64-manylinux_2_38, x86_64-manylinux_2_39, x86_64-manylinux_2_40, aarch64-manylinux2014, aarch64-manylinux_2_17, aarch64-manylinux_2_28, aarch64-manylinux_2_31, aarch64-manylinux_2_32, aarch64-manylinux_2_33, aarch64-manylinux_2_34, aarch64-manylinux_2_35, aarch64-manylinux_2_36, aarch64-manylinux_2_37, aarch64-manylinux_2_38, aarch64-manylinux_2_39, aarch64-manylinux_2_40, aarch64-linux-android, x86_64-linux-android, wasm32-pyodide2024, arm64-apple-ios, arm64-apple-ios-simulator, x86_64-apple-ios-simulator] --torch-backend <TORCH_BACKEND> The backend to use when fetching packages in the PyTorch ecosystem (e.g., `cpu`, `cu126`, or `auto`) [env: UV_TORCH_BACKEND=] [possible values: auto, cpu, cu130, cu129, cu128, cu126, cu125, cu124, cu123, cu122, cu121, cu120, cu118, cu117, cu116, cu115, cu114, cu113, cu112, cu111, cu110, cu102, cu101, cu100, cu92, cu91, cu90, cu80, rocm7.1, rocm7.0, rocm6.4, rocm6.3, rocm6.2.4, rocm6.2, rocm6.1, rocm6.0, rocm5.7, rocm5.6, rocm5.5, rocm5.4.2, rocm5.4, rocm5.3, rocm5.2, rocm5.1.1, rocm4.2, rocm4.1, rocm4.0.1, xpu] Index options: --index <INDEX> The URLs to use when resolving dependencies, in addition to the default index [env: UV_INDEX] --default-index <DEFAULT_INDEX> The URL of the default package index (by default: <https://pypi.org/simple>) [env: UV_DEFAULT_INDEX] -i, --index-url <INDEX_URL> (Deprecated: use `--default-index` instead) The URL of the Python package index (by default: <https://pypi.org/simple>) [env: UV_INDEX_URL] --extra-index-url <EXTRA_INDEX_URL> (Deprecated: use `--index` instead) Extra URLs of package indexes to use, in addition to `--index-url` [env: UV_EXTRA_INDEX_URL] -f, --find-links <FIND_LINKS> Locations to search for candidate distributions, in addition to those found in the registry indexes [env: UV_FIND_LINKS] --no-index Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via `--find-links` --index-strategy <INDEX_STRATEGY> The strategy to use when resolving against multiple index URLs [env: UV_INDEX_STRATEGY=] [possible values: first-index, unsafe-first-match, unsafe-best-match] --keyring-provider <KEYRING_PROVIDER> Attempt to use `keyring` for authentication for index URLs [env: UV_KEYRING_PROVIDER=] [possible values: disabled, subprocess] Resolver options: -U, --upgrade Allow package upgrades, ignoring pinned versions in any existing output file. Implies `--refresh` -P, --upgrade-package <UPGRADE_PACKAGE> Allow upgrades for a specific package, ignoring pinned versions in any existing output file. Implies `--refresh-package` --resolution <RESOLUTION> The strategy to use when selecting between the different compatible versions for a given package requirement [env: UV_RESOLUTION=] [possible values: highest, lowest, lowest-direct] --prerelease <PRERELEASE> The strategy to use when considering pre-release versions [env: UV_PRERELEASE=] [possible values: disallow, allow, if-necessary, explicit, if-necessary-or-explicit] --fork-strategy <FORK_STRATEGY> The strategy to use when selecting multiple versions of a given package across Python versions and platforms [env: UV_FORK_STRATEGY=] [possible values: fewest, requires-python] --exclude-newer <EXCLUDE_NEWER> Limit candidate packages to those that were uploaded prior to the given date [env: UV_EXCLUDE_NEWER=] --exclude-newer-package <EXCLUDE_NEWER_PACKAGE> Limit candidate packages for specific packages to those that were uploaded prior to the given date --no-sources Ignore the `tool.uv.sources` table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any workspace, Git, URL, or local path sources [env: UV_NO_SOURCES=] --no-sources-package <NO_SOURCES_PACKAGE> Don't use sources from the `tool.uv.sources` table for the specified packages [env: UV_NO_SOURCES_PACKAGE=] Installer options: --reinstall Reinstall all packages, regardless of whether they're already installed. Implies `--refresh` --reinstall-package <REINSTALL_PACKAGE> Reinstall a specific package, regardless of whether it's already installed. Implies `--refresh-package` --link-mode <LINK_MODE> The method to use when installing packages from the global cache [env: UV_LINK_MODE=] [possible values: clone, copy, hardlink, symlink] --compile-bytecode Compile Python files to bytecode after installation [env: UV_COMPILE_BYTECODE=] Build options: -C, --config-setting <CONFIG_SETTING> Settings to pass to the PEP 517 build backend, specified as `KEY=VALUE` pairs --config-settings-package <CONFIG_SETTINGS_PACKAGE> Settings to pass to the PEP 517 build backend for a specific package, specified as `PACKAGE:KEY=VALUE` pairs --no-build-isolation Disable isolation when building source distributions [env: UV_NO_BUILD_ISOLATION=] --no-build-isolation-package <NO_BUILD_ISOLATION_PACKAGE> Disable isolation when building source distributions for a specific package --no-build Don't build source distributions [env: UV_NO_BUILD=] --no-build-package <NO_BUILD_PACKAGE> Don't build source distributions for a specific package [env: UV_NO_BUILD_PACKAGE=] --no-binary Don't install pre-built wheels [env: UV_NO_BINARY=] --no-binary-package <NO_BINARY_PACKAGE> Don't install pre-built wheels for a specific package [env: UV_NO_BINARY_PACKAGE=] Cache options: -n, --no-cache Avoid reading from or writing to the cache, instead using a temporary directory for the duration of the operation [env: UV_NO_CACHE=] --cache-dir <CACHE_DIR> Path to the cache directory [env: UV_CACHE_DIR=] --refresh Refresh all cached data --refresh-package <REFRESH_PACKAGE> Refresh cached data for a specific package Python options: -p, --python <PYTHON> The Python interpreter to use to build the run environment. [env: UV_PYTHON=] --managed-python Require use of uv-managed Python versions [env: UV_MANAGED_PYTHON=] --no-managed-python Disable use of uv-managed Python versions [env: UV_NO_MANAGED_PYTHON=] --no-python-downloads Disable automatic downloads of Python. [env: "UV_PYTHON_DOWNLOADS=never"] Global options: -q, --quiet... Use quiet output -v, --verbose... Use verbose output --color <COLOR_CHOICE> Control the use of color in output [possible values: auto, always, never] --native-tls Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=] --offline Disable network access [env: UV_OFFLINE=] --allow-insecure-host <ALLOW_INSECURE_HOST> Allow insecure connections to a host [env: UV_INSECURE_HOST=] --no-progress Hide all progress outputs [env: UV_NO_PROGRESS=] --directory <DIRECTORY> Change to the given directory prior to running the command [env: UV_WORKING_DIR=] --project <PROJECT> Discover a project in the given directory [env: UV_PROJECT=] --config-file <CONFIG_FILE> The path to a `uv.toml` file to use for configuration [env: UV_CONFIG_FILE=] --no-config Avoid discovering configuration files (`pyproject.toml`, `uv.toml`) [env: UV_NO_CONFIG=] -h, --help Display the concise help for this command Use `uvx` as a shortcut for `uv tool run`. Use `uv help tool run` for more details. ``` # Purpose Install and/or run tools from e.g. PyPI. This would provide functionality similar to `npm install -g`. # Notes Trickiest bit is the UI for installing versus running such that running is very short when you don't want to bother installing (`py x`?). Another is whether some version restriction could be picked up from `pyproject.toml` or `pylock.toml`? - `--from`: specify what project to install - Support specifiers - `--spec` from pipx - [`--from` from uv](https://docs.astral.sh/uv/reference/cli/#uv-tool-run--from) - Fallback to `-m` if an entry point with the specified name isn't found? - How long to keep around ephemeral environments? - pipx is 14 days - [uv keeps using the cached version indefinitely](https://docs.astral.sh/uv/concepts/tools/#tool-environments) - Can use `@latest` to always check for a newer version - Provide a way to force a fresh install - If a date-based solution is used, provide a way to specify acceptable staleness? - Use installed version from `tool install` or keep separate from `tool run`? - uv shares, but only when a specifier wasn't used to get a specific thing for `run` - Is it worth having a permanent install versus just supporting `py x`? - It certainly looks cleaner to just say e.g. `nox` than `py x nox` - A permanent install also avoids any network access in case the cached copy is too old - How often do people do a permanent install?