Snapshot your Python venv. Restore it in seconds, anywhere.
Project description
venvsnap
Snapshot a Python virtual environment into a lockfile, then restore it from a local cache. Once the wheels are cached, restoring an env doesn't touch PyPI.
Install
Once published to PyPI:
pip install venvsnap
Until then, install straight from GitHub:
pip install git+https://github.com/VKSFY/venvsnap.git
Requires Python 3.9 or newer.
Usage
In a working venv:
venvsnap snapshot
This walks pip list, looks each package up on PyPI to find a wheel matching
the current platform, and writes the result to venvsnap.lock (TOML). Check
the lockfile in.
On another machine, in CI, or in a fresh clone:
venvsnap restore
This reads the lockfile, downloads any wheels that aren't already in
~/.venvsnap/cache/, creates .venv if needed, and installs everything with
pip install --no-deps --no-index. After the first run for a given lockfile,
no network is involved.
The cache is shared across projects. The first time requests-2.31.0-py3-none-any.whl
gets downloaded, every other project that pins the same wheel reuses the same file.
Other commands
venvsnap verify compare a venv against a lockfile, report drift
venvsnap cache info show the cache path and size
venvsnap cache clean delete every wheel from the cache
--help on any command lists its flags.
Lockfile
venvsnap.lock is plain TOML. A two-package example:
version = 1
python_version = "3.11.7"
platform = "linux-x86_64"
created_at = "2026-04-25T12:34:56Z"
[[package]]
name = "requests"
version = "2.31.0"
sha256 = "58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"
wheel_filename = "requests-2.31.0-py3-none-any.whl"
wheel_url = "https://files.pythonhosted.org/packages/.../requests-2.31.0-py3-none-any.whl"
requires_python = ">=3.7"
[[package]]
name = "rich"
version = "13.7.0"
...
Diffs are readable: a dependency bump shows up as one version/sha256/wheel_url
change.
Cache layout
~/.venvsnap/cache/wheels/<aa>/<sha256>/<filename>.whl
<aa> is the first two hex chars of the sha256, used as a bucket so directories
stay shallow on case-insensitive filesystems. Override with --cache PATH on
any command.
How it compares
pip install -r requirements.txt re-resolves dependencies and consults PyPI on
every run. venvsnap skips the resolver. With a warm cache, restore is wheel
copies plus one pip install invocation.
uv is a faster pip with a real resolver. venvsnap doesn't replace either: use
pip or uv to build the env, then venvsnap snapshot to record it. They compose
fine.
pip-tools writes a pinned requirements file. Install still goes through the
index. venvsnap stores the wheels themselves.
Limits
- Wheels only. If a package only ships an sdist, snapshot warns and skips it.
- PyPI only. Private indexes are not supported in 0.1.
- No resolver. venvsnap captures whatever is already installed; building the env is somebody else's job.
Benchmark
examples/benchmark.py installs a small dependency set with pip install -r,
then runs venvsnap restore cold and warm, and prints the times. Numbers vary
with bandwidth and hardware, so run it locally.
python examples/benchmark.py
Development
git clone https://github.com/VKSFY/venvsnap
cd venvsnap
python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest
ruff check, ruff format --check, mypy src, and pytest all run in CI on
push.
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file venvsnap-0.1.0.tar.gz.
File metadata
- Download URL: venvsnap-0.1.0.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb784685db736fb9023c9ac72ab0d511b3f58f0fb417729a8b71793b95e19ddb
|
|
| MD5 |
f63294cc986bd255d6a097439bce8c7d
|
|
| BLAKE2b-256 |
5d808b83bbc9fe6fbeeb335db787890b8fe334c3e241e4b593e748299ed1aa2e
|
Provenance
The following attestation bundles were made for venvsnap-0.1.0.tar.gz:
Publisher:
release.yml on VKSFY/venvsnap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
venvsnap-0.1.0.tar.gz -
Subject digest:
eb784685db736fb9023c9ac72ab0d511b3f58f0fb417729a8b71793b95e19ddb - Sigstore transparency entry: 1436171362
- Sigstore integration time:
-
Permalink:
VKSFY/venvsnap@326bbf5743a2446401a2901a6a38ce5020d3a7a7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/VKSFY
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@326bbf5743a2446401a2901a6a38ce5020d3a7a7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file venvsnap-0.1.0-py3-none-any.whl.
File metadata
- Download URL: venvsnap-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6dcc234fa057a7c09ee65ece71569e9fa062d7d055fed3059f2f476696a80d8d
|
|
| MD5 |
fc9a2b400c73b0335de89f44c05e75a5
|
|
| BLAKE2b-256 |
c83afae109f682ea7a40e16d0b442ae94322a3b6628eb3a59d57f66717b7cad1
|
Provenance
The following attestation bundles were made for venvsnap-0.1.0-py3-none-any.whl:
Publisher:
release.yml on VKSFY/venvsnap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
venvsnap-0.1.0-py3-none-any.whl -
Subject digest:
6dcc234fa057a7c09ee65ece71569e9fa062d7d055fed3059f2f476696a80d8d - Sigstore transparency entry: 1436171369
- Sigstore integration time:
-
Permalink:
VKSFY/venvsnap@326bbf5743a2446401a2901a6a38ce5020d3a7a7 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/VKSFY
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@326bbf5743a2446401a2901a6a38ce5020d3a7a7 -
Trigger Event:
push
-
Statement type: