Skip to content

LinuxMainframe/packwarden

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

packwarden

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.


Features

  • 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, and brew as 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

Installation

pip install packwarden

Usage

From a parent program

from 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 plt

Passing a requirements.txt

from pathlib import Path
from packwarden import check_dependencies

status, info = check_dependencies(
    requirements=Path("requirements.txt").read_text().splitlines(),
)

Silent / CI mode

status, info = check_dependencies(["pandas"], silent=True)
# Returns PACKAGES_ERROR immediately if anything is missing.
# No prompts, no output.

Standalone diagnostic

# 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 --silent

Return value

check_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

Error codes

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

Security

  • 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=True is 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.

License

MIT — see LICENSE.

About

A self-contained, drop-in Python dependency management module

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages