A self-contained, drop-in Python dependency management module.
Handles first-time installs, returning users, and confused environments (path/venv mismatches) — with zero runtime dependencies of its own.
- Detects whether you are in a venv, conda env, or system Python
- Identifies missing packages and offers to install them
- Supports
apt,dnf,pacman,zypper, andbrewas system-level install options for managed/shared machines - Detects environment confusion (saved config disagrees with active env)
- Collects OS and hardware info to guide install decisions
- Validates all package names before passing them to any subprocess
- Never uses
shell=True— no shell injection vectors - Stores only filesystem paths and timestamps — no credentials or PII
- Works on Python 3.8+, zero external dependencies
pip install packwardenfrom packwarden import check_dependencies, PACKAGES_OK, PACKAGES_ERROR
status, info = check_dependencies(["pandas", "matplotlib", "scipy"])
if status == PACKAGES_ERROR:
print(f"Setup failed: {info['error_code']}")
raise SystemExit(1)
if info.get("requires_relaunch"):
# A new venv was created. The user must activate it and re-run.
print("Please activate your environment and re-run the script:")
print(f" {info['activate_hint']}")
raise SystemExit(0)
# All packages are present — safe to import.
import pandas as pd
import matplotlib.pyplot as pltfrom pathlib import Path
from packwarden import check_dependencies
status, info = check_dependencies(
requirements=Path("requirements.txt").read_text().splitlines(),
)status, info = check_dependencies(["pandas"], silent=True)
# Returns PACKAGES_ERROR immediately if anything is missing.
# No prompts, no output.# Dump full system info as JSON
packwarden
# Check specific packages
packwarden pandas matplotlib scipy
# Check from a requirements file
packwarden -r requirements.txt
# Non-interactive (CI/CD)
packwarden pandas --silentcheck_dependencies() always returns a (status, info) tuple.
status, info = check_dependencies(["requests"])status is one of:
| Value | Meaning |
|---|---|
PACKAGES_OK |
All packages are importable |
PACKAGES_ERROR |
Something went wrong or the user cancelled |
info always contains:
| Key | Type | Description |
|---|---|---|
"system" |
dict |
OS, environment, and hardware snapshot |
On error, info also contains:
| Key | Type | Description |
|---|---|---|
"error_code" |
str |
An ErrorCode value (see below) |
"missing" |
list[str] |
Packages that could not be installed |
"pip_output" |
str |
pip stderr/stdout if install was attempted |
On success after a fresh venv install, info also contains:
| Key | Type | Description |
|---|---|---|
"requires_relaunch" |
bool |
Parent must relaunch inside the new venv |
"activate_hint" |
str |
The activation command to show the user |
"venv_path" |
str |
Path to the newly created venv |
from packwarden import ErrorCode
ErrorCode.USER_CANCELLED # User declined a prompt
ErrorCode.INSTALL_FAILED # pip or package manager returned non-zero
ErrorCode.PERMISSION_DENIED # Filesystem or sudo permission error
ErrorCode.ENV_CONFUSED # Config disagrees with active environment
ErrorCode.VENV_CREATE_FAIL # Could not create a venv
ErrorCode.PIP_UNAVAILABLE # pip not found for this Python interpreter
ErrorCode.INVALID_REQUIREMENT # A requirement failed validation
ErrorCode.LOW_DISK_SPACE # Not enough free space to install
ErrorCode.UNKNOWN # Catch-all- No network calls are made by this module directly. All network activity is delegated to pip or the system package manager.
- All package names are validated against a strict allowlist regex before being passed to any subprocess.
shell=Trueis never used.- Requirements from files are sanitised to reject pip flags, URLs, and local paths — only standard PyPI package names are accepted.
- The config file stores only local filesystem paths and timestamps. No credentials, tokens, or personal information are written.
MIT — see LICENSE.