px manages Python project dependencies using immutable environment profiles.
Instead of treating "the environment" as a directory you activate and mutate, px builds a profile into a global, content-addressed store and can run directly from it. A venv-style on-disk env or a sandbox is optional and generated on demand.
cargo install --path crates/px-cli --locked
px --versionIf you don't have a px-managed Python runtime yet, px will offer to install one on first use. This demo script requires Python >=3.12.
Run a script straight from this repo's HEAD. Default is commit-pinned; --allow-floating allows HEAD and branches:
px run --allow-floating https://github.com/ck-zhang/px/blob/HEAD/fixtures/run_by_reference_demo/scripts/whereami.pyRun the same script in a Linux sandbox. Requires podman or docker; first run may take longer:
px run --allow-floating --sandbox https://github.com/ck-zhang/px/blob/HEAD/fixtures/run_by_reference_demo/scripts/whereami.pyIn a Python project directory:
px init
px add requests rich
mkdir -p tests
cat > tests/test_smoke.py <<'PY'
def test_smoke():
import requests, rich
assert True
PY
px test
px run python -c "import requests, rich; print('ok')"If you cloned a repo that does not use px:
px migrate --apply
px testpyproject.toml- declared intentpx.lock- resolved, exact set
.px/- local state and logs. Built artifacts live under~/.px/.
px add <pkg>.../px remove <pkg>...- update dependenciespx run <target> [...args]- run commandspx test- run testspx sync- ensure the local profile matches the lockfile; use--frozenin CI
px executes from a content-addressed store of built artifacts:
- no activation step
- no accidental mutation via ad-hoc installs
- identical dependency graphs can reuse the same artifacts across projects
If you need a directory-based layout for compatibility or sandboxing, px can materialize one. It's a generated view and not the source of truth.
When packages need compilation, px builds them inside pinned builder environments. This reduces dependence on the host machine's toolchain and helps keep CI and developer machines consistent.
Sandboxing is an execution mode derived from the same profile plus sandbox config:
- use it when you need container parity or system libraries
- skip it when you want the fastest local loop
px sync --frozen
px test --frozen# /// script
# requires-python = ">=3.11"
# dependencies = ["httpx"]
# ///px run path/to/script.pypx run --sandbox python -c "print('ok')"
px test --sandboxpx pack app --out dist/myapp.pxapp
px run dist/myapp.pxappTip: for library-only projects, set an entrypoint with px pack app --entrypoint "python -m your_module".
px tool install black
px tool run black --check .px status- check whether manifest / lock / profile agreepx explain run ...- show what px would run and whypx why <package>- show why a dependency is present
docs/index.md