managing a local environment
Project description
venvmngr — Manage Python virtual environments (venv and uv)
venvmngr is a tiny, pragmatic toolkit for creating and managing Python virtual environments from code or a simple CLI. It currently supports two backends:
- Standard library venv + pip (simple, zero extra tools)
- uv-backed workflow (pyproject.toml + uv add/remove/lock/sync)
It’s designed to be embedded in other apps or automation, with streaming callbacks for subprocess output and a straightforward API.
Highlights
- Two backends: built-in venv/pip and uv/pyproject
- Clean Python API with sensible defaults
- Simple CLI for common tasks (create, install, list, update-check)
- Streaming stdout/stderr callbacks for progress reporting
- Utilities to locate system Python interpreters
- Optional integration with subprocess-monitor for non-blocking module runs
Installation
- pip:
pip install venvmngr - uv:
uv add venvmngr
Requirements
- Python >= 3.9
- Runtime deps: requests, packaging, uv (for uv workflow), subprocess-monitor (optional), psutil (optional)
- psutil and subprocess-monitor are only used when you opt into non-blocking process runs via
SUBPROCESS_MONITOR_PORT.
- psutil and subprocess-monitor are only used when you opt into non-blocking process runs via
Quickstart
CLI (venv/pip backend)
The CLI manages a specific environment directory and uses the standard venv + pip flow.
Examples:
-
Create an environment:
python -m venvmngr --env .venv create- or, after installing:
venvmngr --env .venv create
-
Install a package:
venvmngr --env .venv install requests- with a version:
venvmngr --env .venv install requests --version 2.32.3 - upgrade:
venvmngr --env .venv install requests --upgrade
-
List packages:
venvmngr --env .venv list
-
Check for updates of a specific package:
venvmngr --env .venv update-check requests
Python API (venv/pip backend)
Use the VenvManager to create and manage a venv-driven environment:
from venvmngr import VenvManager
# Create or open an environment
mngr, created = VenvManager.get_or_create_virtual_env(".venv")
# Install packages (supports exact pins and specifiers)
mngr.install_package("requests", version=">=2.31")
# List packages
for pkg in mngr.all_packages():
print(pkg["name"], pkg["version"]) # version is a packaging.version.Version
# Check for updates (compares to PyPI)
update, latest, current = mngr.package_update_available("requests")
if update:
print(f"Update available: {current} -> {latest}")
# Run a module inside the venv
mngr.run_module("pip", ["--version"]) # blocks by default
uv Workflow (pyproject + uv)
Use UVVenvManager when a project uses pyproject.toml and the uv tool:
from pathlib import Path
from venvmngr import UVVenvManager
project = Path("/path/to/project")
toml = project / "pyproject.toml"
# Create or open a uv environment
uv_mngr, created = UVVenvManager.get_or_create_virtual_env(toml)
# Install a dependency via `uv add` and sync the environment
uv_mngr.install_package("httpx", version=">=0.27")
# Remove a dependency
uv_mngr.remove_package("httpx")
# List packages (delegates to pip inside the created venv)
for pkg in uv_mngr.all_packages():
print(pkg)
Notes:
UVVenvManagerruns uv commands in the project directory that containspyproject.toml.- By default the environment directory is
.venv(can be overridden withUV_PROJECT_ENVIRONMENT).
Key Concepts and API
Public imports from venvmngr:
VenvManager— venv/pip managerUVVenvManager— uv-backed managercreate_virtual_env(path, ...)— alias toVenvManager.create_virtual_envget_or_create_virtual_env(path, ...)— alias toVenvManager.get_or_create_virtual_envget_virtual_env(path)— alias toVenvManager.get_virtual_envlocate_system_pythons()— discover system Python interpretersget_python_executable()— robust Python path resolution (PyInstaller-aware)
VenvManager
-
create_virtual_env(env_path, min_python=None, max_python=None, use="default", python_executable=None, stdout_callback=None, stderr_callback=None) -> VenvManager- Creates a venv with the chosen interpreter.
- If
python_executableis not provided, probes system interpreters withlocate_system_pythons()and optionally filters by version range. use="latest"chooses the highest compatible version.
-
get_or_create_virtual_env(env_path, **kwargs) -> (VenvManager, bool)- Returns a manager and a flag indicating whether the env was created.
-
get_virtual_env(env_path) -> VenvManager- Opens an existing environment. Raises if invalid.
-
install_package(name, version=None, upgrade=False, stdout_callback=None, stderr_callback=None)- Installs via
pip install.versioncan be exact (e.g."2.2.0", becomesname==2.2.0) or a specifier (e.g.">=2.2.0"). - Underscores in names are normalized to hyphens.
- Installs via
-
all_packages() -> list[dict]- Returns
[{"name": str, "version": Version}, ...]usingpip list --format=json.
- Returns
-
remove_package(name)- Uninstalls via
pip uninstall -y.
- Uninstalls via
-
package_is_installed(name) -> bool,get_package_version(name) -> Version | None -
package_update_available(name) -> (bool, Version | None, Version | None)- Compares local version to PyPI’s latest (via the PyPI JSON API).
-
run_module(module, args: list[str] = [], block: bool = True, **kwargs)- Executes
python -m <module>inside the env. Ifblock=True, returnssubprocess.CompletedProcess. - If
block=FalseandSUBPROCESS_MONITOR_PORTis set, integrates withsubprocess-monitorand returns apsutil.Process(kills the process if the manager dies). Otherwise returns asubprocess.Popen.
- Executes
UVVenvManager (inherits VenvManager)
-
create_virtual_env(toml_path, python=None, description=None, stdout_callback=None, stderr_callback=None) -> UVVenvManager- Ensures
pyproject.tomlexists (creates a minimal one withuv initif missing) and creates a uv-managed venv (uv venv). - Installs/updates
pipinside the env.
- Ensures
-
get_or_create_virtual_env(toml_path, **kwargs) -> (UVVenvManager, bool)- Uses
pyproject.tomland the default venv directory (usually.venv).
- Uses
-
get_virtual_env(path) -> UVVenvManager- Accepts either an env directory or a
pyproject.tomlpath.
- Accepts either an env directory or a
-
install_package(name, version=None, upgrade=False, stdout_callback=None, stderr_callback=None)- Uses
uv add, optionallyuv lock --upgrade-package <name>, thenuv sync.
- Uses
-
remove_package(name)- Uses
uv removeanduv sync.
- Uses
-
get_default_venv_name() -> str- Defaults to
.venv, overridable viaUV_PROJECT_ENVIRONMENT.
- Defaults to
Utilities
-
locate_system_pythons()- Uses
where(Windows) orwhich(POSIX) to findpythonexecutables and probes them for versions.
- Uses
-
run_subprocess_with_streams(args, stdout_callback=None, stderr_callback=None)- Runs a subprocess and streams lines to the provided callbacks, raising on non-zero exit.
-
get_python_executable()- Returns a robust Python interpreter path; handles PyInstaller contexts by falling back to a system Python.
Callbacks and Streaming Output
Package installation, uv operations, and environment creation can stream progress lines via stdout_callback and stderr_callback callables:
def on_out(line: str):
print(line, end="")
def on_err(line: str):
print(line, end="")
mngr.install_package("pip", upgrade=True, stdout_callback=on_out, stderr_callback=on_err)
Choosing a Python Version (venv backend)
When creating an environment with VenvManager.create_virtual_env(...), you can:
- Provide an explicit interpreter:
python_executable="/usr/bin/python3.12" - Constrain versions and let venvmngr choose from discovered interpreters:
min_python="3.11",max_python="3.12",use="latest"
Example:
VenvManager.create_virtual_env(
".venv",
min_python="3.11",
max_python="3.12",
use="latest",
)
CLI Reference
Base invocation: venvmngr --env <path> <command> [options]
create— Create a new environment at--env.install <package> [--version <ver>] [--upgrade]— Install a package (exact pin or specifier).list— List installed packages.update-check <package>— Compare installed version to PyPI.
Note: The CLI targets the venv/pip backend. The uv manager is currently exposed via the Python API.
Development
- Use uv for dev setup:
uv sync --devuv run pytest -q
- Lint/format via pre-commit (ruff, flake8):
uv run pre-commit run -a
- Project configuration: see
pyproject.toml
License
MIT — see LICENCE for details.
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 venvmngr-0.2.0.tar.gz.
File metadata
- Download URL: venvmngr-0.2.0.tar.gz
- Upload date:
- Size: 125.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3edd4d31a068a23fa081542b3d0ce53d2f92d95e0eee5881e4c95b25d074f8d5
|
|
| MD5 |
669d36050989cef3d8e70a5b507f4470
|
|
| BLAKE2b-256 |
676beb6f900a5c319c8728326fddfd39297be59fb429c3d6fa213922385b23e0
|
Provenance
The following attestation bundles were made for venvmngr-0.2.0.tar.gz:
Publisher:
version_publish_main.yml on JulianKimmig/venvmanager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
venvmngr-0.2.0.tar.gz -
Subject digest:
3edd4d31a068a23fa081542b3d0ce53d2f92d95e0eee5881e4c95b25d074f8d5 - Sigstore transparency entry: 621365729
- Sigstore integration time:
-
Permalink:
JulianKimmig/venvmanager@764fe5f89c35c9053e3b65e7940b6211cbd7c8b8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JulianKimmig
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
version_publish_main.yml@764fe5f89c35c9053e3b65e7940b6211cbd7c8b8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file venvmngr-0.2.0-py3-none-any.whl.
File metadata
- Download URL: venvmngr-0.2.0-py3-none-any.whl
- Upload date:
- Size: 20.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4858b3d07137e8ef65b055034a92011c053b7a55c169e10e6c8d7b17b730669
|
|
| MD5 |
eb000cf9687b73d278571c693a4c9b58
|
|
| BLAKE2b-256 |
cc01a71620f0d11ab4a715f0265c554d98d44553be99ce7bb5a90db31def9328
|
Provenance
The following attestation bundles were made for venvmngr-0.2.0-py3-none-any.whl:
Publisher:
version_publish_main.yml on JulianKimmig/venvmanager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
venvmngr-0.2.0-py3-none-any.whl -
Subject digest:
c4858b3d07137e8ef65b055034a92011c053b7a55c169e10e6c8d7b17b730669 - Sigstore transparency entry: 621365730
- Sigstore integration time:
-
Permalink:
JulianKimmig/venvmanager@764fe5f89c35c9053e3b65e7940b6211cbd7c8b8 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JulianKimmig
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
version_publish_main.yml@764fe5f89c35c9053e3b65e7940b6211cbd7c8b8 -
Trigger Event:
push
-
Statement type: