Skip to content

pointmatic/pyve

Pyve

Pyve: Python Virtual Environment Manager

Tests codecov License

A command-line tool that simplifies setting up and managing Python virtual environments on macOS and Linux, orchestrating Python version managers, venv and micromamba backends, and direnv in a single script.

See https://pointmatic.github.io/pyve/ for more information.

Why Pyve?

Pyve is a focused command-line tool that provides a single, deterministic entry point for setting up and managing Python virtual environments on macOS and Linux. It orchestrates Python version management (asdf or pyenv), virtual environments (venv or micromamba), and direnv integration in one script. It supports interactive workflows with auto-activation and non-interactive CI/CD pipelines with explicit execution via pyve run.

  • One-command environment setup (pyve init)
  • Dual backend support — venv (pip) and micromamba (conda-compatible)
  • Automatic Python version management via asdf or pyenv
  • direnv integration for seamless shell activation
  • CI/CD-ready with --no-direnv, --auto-bootstrap, and --strict flags
  • Clean teardown with pyve purge — preserves your secrets
  • Zero runtime dependencies — pure Bash, no daemons

Philosophy

Make things easy and natural, but avoid being invasive.

  • Pyve manages the environments it creates.
  • Pyve asks before installing non-critical, networked dependencies like micromamba or pytest.
  • If you prefer asdf instead of venv, Pyve will automatically detect and use it to manage the virtual environment for you.
  • Pyve does not install conda-lock, but wraps its invocation via pyve lock when it is available — handling platform detection and suppressing the misleading post-run message.

Key Features

  • Install: Install Pyve via Homebrew (brew install pointmatic/tap/pyve) or manually from source (./pyve.sh self install, which copies the script to ~/.local/bin/ and creates a symlink).
  • Init: Pyve will automatically initialize your Python coding environment as a virtual environment with your specified (or the default) version of Python and configure direnv to autoactivate and deactivate your virtual environment when you change directories.
    • Re-Init: Refresh your Pyve initialization using pyve init --force. This will first purge, then initialize Pyve in one commmand.
  • Purge: Remove all the Pyve setup and artifacts, except if you've added any secrets to the .env file, Pyve will leave it and let you know that.

Conceptual Model

Pyve separates three concerns:

  1. Python runtime selection

    • Provided by asdf or pyenv
    • Determines which Python version is used
  2. Environment backend

    • venv (pip-based) for application and development workflows
    • micromamba (conda-compatible) for scientific / ML workflows
  3. Activation and execution

    • direnv for interactive shell convenience
    • Pyve commands for deterministic environment setup and execution

Execution Model (Preview)

Pyve is designed around explicit environment execution.

While interactive shells typically rely on direnv for automatic activation, Pyve commands may execute tools directly inside the project environment without requiring manual activation.

This model avoids reliance on shell state and improves reproducibility for scripts, automation, and CI workflows.

Requirements

  • macOS or Linux with Bash
  • Either of these Python version managers:
    • asdf (recommended, with Python plugin). Pyve auto-installs requested Python versions.
    • pyenv. Pyve auto-installs requested Python versions.
  • direnv (required for pyve init; not required for standalone pyve python-version)
  • micromamba (optional):
    • Required only when initializing conda-compatible environments
    • Used for ML / scientific stacks that benefit from binary dependencies

The script checks for prerequisites and provides helpful error messages if anything is missing.

Quick Start

Install via Homebrew (recommended):

brew install pointmatic/tap/pyve
pyve --help

Or install from source:

git clone git@github.com:pointmatic/pyve.git; cd pyve; ./pyve.sh self install; pyve --help

Initialize a Python Virtual Environment

Go to the root of your project directory and run pyve init to initialize your Python virtual environment.

In a single command, Pyve will:

  • Set Python version: Uses asdf or pyenv to set the Python version (default: 3.14.3)
  • Create virtual environment: Creates .venv directory with Python venv
  • Upgrade pip: Automatically upgrades pip to the latest version for security and features
  • Configure direnv: Sets up .envrc for automatic activation when entering the directory
  • Create .env file: Sets up a secure environment variables file (chmod 600)
  • Update .gitignore: Adds appropriate patterns to keep secrets out of version control

Purge

Run pyve purge to cleanly remove all Pyve-created artifacts:

  • Removes .venv directory
  • Removes .tool-versions or .python-version file
  • Removes .envrc file
  • Smart .env handling: Only removes .env if empty; preserves files with your data
  • Cleans up .gitignore patterns (keeps the file itself)

Installation

Homebrew (recommended)

brew install pointmatic/tap/pyve

To update:

brew upgrade pointmatic/tap/pyve

From Source

  1. Clone this repository:

    git clone git@github.com:pointmatic/pyve.git
    cd pyve
  2. Install to your local bin directory:

    ./pyve.sh self install

This will:

  • Create ~/.local/bin (if needed)
  • Copy pyve.sh and lib/ helpers to ~/.local/bin
  • Create a pyve symlink
  • Add ~/.local/bin to your PATH (via ~/.zprofile or ~/.bash_profile)
  • Create ~/.local/.env template for shared environment variables

After installation, run pyve from any directory.

Usage

Initialize a Python Virtual Environment

By default, pyve init creates a Python venv-based backend or auto-detects from project files.

Backend Selection

pyve init                          # Auto-detect or default to venv
pyve init --backend venv           # Explicit venv backend
pyve init --backend micromamba     # Explicit micromamba backend
pyve init --backend auto           # Auto-detect from files

Standard Options

pyve init my_venv                    # Custom venv directory name
pyve init --python-version 3.12.0    # Specific Python version
pyve init --local-env                # Copy ~/.local/.env template to .env

Backend Auto-Detection Priority

When --backend is not specified, Pyve automatically detects the appropriate backend using this precedence:

  1. .pyve/config - Explicit project configuration (highest priority)

    # .pyve/config
    backend: micromamba
  2. environment.yml / conda-lock.yml - Conda environment files → micromamba backend

    # environment.yml present → uses micromamba
    name: myproject
    dependencies:
      - python=3.11
      - numpy
  3. pyproject.toml / requirements.txt - Python package files → venv backend

    # pyproject.toml present → uses venv
    [project]
    name = "myproject"
    dependencies = ["requests", "flask"]
  4. Default to venv - When no environment files exist

Ambiguous Cases (Interactive Prompt):

When both conda and Python files exist (e.g., environment.yml + pyproject.toml), Pyve prompts you to choose:

Detected files:
  • environment.yml (conda/micromamba)
  • pyproject.toml (Python project)

Initialize with micromamba backend? [Y/n]:
  • Interactive mode: Prompts user, defaults to micromamba (press Enter or type Y)
  • CI mode: Automatically uses micromamba without prompting (when CI environment variable is set)
  • Override: Use --backend flag to skip the prompt

Examples:

# Project with environment.yml → automatically uses micromamba
cd my-ml-project
pyve init  # Detects environment.yml, uses micromamba

# Project with requirements.txt → automatically uses venv
cd my-web-app
pyve init  # Detects requirements.txt, uses venv

# Empty project → defaults to venv
cd new-project
pyve init  # No files detected, uses venv

# Ambiguous project → prompts for choice
cd ml-project-with-both-files
pyve init  # Prompts: "Initialize with micromamba backend? [Y/n]:"

# Override auto-detection
pyve init --backend micromamba  # Force micromamba (skip prompt)
pyve init --backend venv         # Force venv (skip prompt)

Backend Comparison

Feature venv micromamba
Package Manager pip conda/mamba
Best For Pure Python, web apps, APIs Data science, ML, scientific computing
Binary Dependencies Limited (via wheels) Excellent (conda packages)
Environment File requirements.txt, pyproject.toml environment.yml, conda-lock.yml
Lock Files requirements.txt (pip-tools) conda-lock.yml
Activation source .venv/bin/activate micromamba activate or pyve run
Speed Fast (pip) Fast (micromamba is faster than conda)
Disk Space Smaller Larger (includes compiled binaries)
Cross-Platform Python-only packages Full cross-platform support
Channel Support PyPI only conda-forge, defaults, custom channels
Python Version Managed by asdf/pyenv Can be in environment.yml

When to use venv:

  • Pure Python projects
  • Web applications and APIs
  • Projects with only PyPI dependencies
  • Smaller disk footprint needed

When to use micromamba:

  • Data science and ML projects
  • Projects requiring NumPy, Pandas, TensorFlow, PyTorch
  • Projects with C/C++ dependencies
  • Cross-platform reproducibility needed
  • Projects already using conda/mamba

Note: On Python 3.12+, Pyve installs a lightweight distutils compatibility shim (via sitecustomize.py) to avoid TensorFlow/Keras import failures in environments that still import distutils. Disable with PYVE_DISABLE_DISTUTILS_SHIM=1.

Pip Dependency Installation

After creating the environment, Pyve prompts to install pip dependencies if pyproject.toml or requirements.txt exists:

Install pip dependencies from pyproject.toml? [Y/n]:

This runs pip install -e . to install your project in editable mode, making your code importable as a package.

Behavior:

  • Interactive mode: Prompts user (default: Yes, press Enter or type Y)
  • Auto-install: Use --auto-install-deps flag to install without prompting
  • Skip prompt: Use --no-install-deps flag to skip installation
  • CI mode: Skipped by default (set PYVE_AUTO_INSTALL_DEPS=1 to enable in CI)

Examples:

# Standard initialization (prompts for pip dependencies)
pyve init

# Auto-install dependencies without prompting
pyve init --auto-install-deps

# Skip dependency installation prompt (useful for CI)
pyve init --no-install-deps

# CI/CD with auto-install
PYVE_AUTO_INSTALL_DEPS=1 pyve init --no-direnv

After setup, run direnv allow to activate the environment.

Set Python Version Only

pyve python-version 3.13.7

Sets the Python version in the current directory (via asdf or pyenv) without creating a virtual environment.

Remove Environment

pyve purge                           # Remove all artifacts
pyve purge my_venv                   # Remove custom-named venv
pyve purge --keep-testenv            # Preserve the dev/test runner environment

Testing (v1.5.2)

The Pyve codebase is tested using pytest. The test suite is located in the tests directory. There are both unit tests and integration tests.

As a tool, Pyve supports the developer with an isolated test environment.

The dev/test runner environment

Pyve supports integration testing via a dedicated dev/test runner environment separate from the project runtime virtual environment. When you run pyve test, Pyve will initialize the dev/test runner environment. If pytest is missing, Pyve prompts to install pytest (interactive shell).

  • Project environment: .venv/ (created by pyve init)
  • Dev/test runner environment: .pyve/testenv/venv/ (used by pyve test)

This separation prevents destructive actions like pyve init --force from wiping your test tooling.

Running tests

Run pytest via Pyve:

pyve test
pyve test -q
pyve test tests/integration/test_testenv.py

If pytest is not installed in the dev/test runner environment:

  • In an interactive terminal, Pyve will prompt:
    • pytest is not installed in the dev/test runner environment. Install now? [y/N]
  • In non-interactive contexts, Pyve will exit with instructions.

You can also install dev/test dependencies explicitly:

pyve testenv --init
pyve testenv --install -r requirements-dev.txt

All Commands

# Environment
pyve init                 # Initialize your Python coding environment
pyve purge                # Remove environment artifacts
pyve python-version <ver> # Set Python version only
pyve lock                 # Generate/update conda-lock.yml (micromamba projects)

# Execution
pyve run <cmd>            # Execute command in project environment
pyve test [pytest args]   # Run pytest via the dev/test runner environment
pyve testenv <subcommand> # Manage the dev/test runner environment

# Diagnostics
pyve doctor               # Check environment health and configuration
pyve validate             # Validate installation and configuration

# Self management
pyve self install         # Install pyve to ~/.local/bin
pyve self uninstall       # Remove pyve from ~/.local/bin

# Universal flags
pyve --help, -h           # Show help
pyve --version, -v        # Show version
pyve --config, -c         # Show configuration

# Per-command help
pyve <command> --help     # Show focused help for a specific command

Configuration

Project Configuration File

Create .pyve/config for explicit backend and environment settings:

# .pyve/config
backend: micromamba

micromamba:
  env_name: myproject
  env_file: environment.yml
  channels:
    - conda-forge
    - defaults
  prefix: .pyve/envs/myproject

python:
  version: "3.11"

venv:
  directory: .venv

Environment Variables

  • Project-specific: .env file in your project root for secrets and environment variables
  • User template: ~/.local/.env serves as a template copied to new projects with --init --local-env

CLI Flags

Run pyve --help for all available commands and options.

Uninstallation

Homebrew

brew uninstall pyve

From Source

pyve self uninstall

This removes:

  • ~/.local/bin/pyve symlink
  • ~/.local/bin/pyve.sh script
  • ~/.local/bin/lib/ helper scripts
  • ~/.local/.env (only if empty)
  • PATH entry from shell profile (if added by pyve)

Contributing

See CONTRIBUTING.md for contribution guidelines.

Troubleshooting

The script checks for prerequisites (asdf/pyenv, direnv) before initialization and provides helpful error messages if anything is missing.

Direct execution: You can run the script directly without installing: ./pyve.sh init

Diagnostic Command

Check environment health and configuration:

pyve doctor                          # Check environment health
pyve doctor --backend micromamba     # Check micromamba setup
pyve doctor --verbose                # Detailed diagnostics

Micromamba Bootstrap

Pyve can automatically install micromamba when needed, with both interactive and non-interactive modes.

Interactive Bootstrap

When micromamba backend is required but not found, Pyve prompts for installation:

ERROR: Backend 'micromamba' required but not found.

Detected: environment.yml
Required: micromamba

Installation options:
  1. Install to project sandbox: .pyve/bin/micromamba
  2. Install to user sandbox: ~/.pyve/bin/micromamba
  3. Install via system package manager (brew/apt)
  4. Abort and install manually

Choice [1]: _

Installation Locations:

  • Project sandbox (.pyve/bin/micromamba) - Isolated per-project, gitignored
  • User sandbox (~/.pyve/bin/micromamba) - Shared across projects, in home directory
  • System package manager - Uses brew (macOS) or apt (Linux)
  • Manual - Exit and install yourself

Auto-Bootstrap (Non-Interactive)

For CI/CD and automation, use --auto-bootstrap to skip prompts:

# Auto-bootstrap to user sandbox (default)
pyve init --backend micromamba --auto-bootstrap

# Explicitly specify installation location
pyve init --backend micromamba --auto-bootstrap --bootstrap-to user
pyve init --backend micromamba --auto-bootstrap --bootstrap-to project

# CI/CD example
pyve init --backend micromamba --auto-bootstrap --no-direnv

Bootstrap Flags:

  • --auto-bootstrap - Install micromamba automatically without prompting
  • --bootstrap-to project - Install to .pyve/bin/micromamba (project-local)
  • --bootstrap-to user - Install to ~/.pyve/bin/micromamba (user-wide)

Environment Naming

Pyve automatically resolves environment names for micromamba using this priority:

  1. --env-name flag - Explicit CLI override (highest priority)

    pyve init --backend micromamba --env-name myproject-dev
  2. .pyve/config file - Project configuration

    micromamba:
      env_name: myproject
  3. environment.yml name field - From environment file

    name: myproject
    dependencies:
      - python=3.11
  4. Project directory basename - Sanitized directory name (default)

    # In /path/to/my-ml-project
    pyve init --backend micromamba
    # Environment name: my-ml-project

Name Sanitization:

  • Converts to lowercase
  • Replaces spaces and special characters with hyphens
  • Removes leading/trailing hyphens
  • Reserved names rejected: base, root, default, conda, mamba, micromamba

Examples:

# Explicit name
pyve init --backend micromamba --env-name my-env

# From environment.yml
cat > environment.yml << EOF
name: data-science-project
dependencies:
  - python=3.11
  - pandas
EOF
pyve init  # Uses name: data-science-project

# Auto-generated from directory
cd "My ML Project"
pyve init --backend micromamba  # Environment: my-ml-project

Lock File Validation

Pyve validates conda lock files to ensure reproducibility:

Lock File Status

pyve doctor  # Check lock file status

Status Indicators:

  • Up to date - conda-lock.yml newer than environment.yml
  • Stale - environment.yml modified after conda-lock.yml
  • Missing - No conda-lock.yml found

Strict Mode

Use --strict to enforce lock file requirements:

# Error if lock file is stale or missing
pyve init --backend micromamba --strict

# Useful for CI/CD to ensure reproducibility
pyve init --backend micromamba --strict --auto-bootstrap --no-direnv

Strict Mode Behavior:

  • Missing lock file - Exits with error, suggests generating with conda-lock
  • Stale lock file - Exits with error, shows timestamps, suggests regenerating
  • Up-to-date lock file - Proceeds normally

Generate Lock Files:

# Generate lock file for the current platform (recommended)
pyve lock

# Or invoke conda-lock directly (must know your platform string)
conda-lock -f environment.yml -p osx-arm64  # macOS Apple Silicon
conda-lock -f environment.yml -p linux-64   # Linux x86_64

Example Output (Stale Lock File):

⚠ Lock file: conda-lock.yml (stale)
  environment.yml: 2026-01-06 02:15:30
  conda-lock.yml:  2026-01-05 18:42:15

ERROR: Lock file is stale (--strict mode)
Regenerate with: conda-lock -f environment.yml

Commands

pyve run - For CI/CD and Automation

Note for interactive use: If you're using direnv (the default), you don't need pyve run. Just cd into your project and run commands normally. The environment auto-activates.

When you need pyve run:

  • CI/CD pipelines (GitHub Actions, GitLab CI, etc.)
  • Docker containers without direnv
  • Automation scripts that need explicit environment execution
  • Projects initialized with --no-direnv

When you DON'T need it:

  • Interactive terminal use with direnv (just use cd + normal commands)
  • Local development with direnv active
pyve run <command> [args...]

Arguments:

  • <command>: The executable to run (python, pytest, pip, black, etc.)
  • [args...]: Optional arguments passed to the command

Interactive Use (with direnv - most users):

cd /path/to/project    # direnv auto-activates environment
python --version       # Just run commands normally
pytest                 # No pyve run needed
pip install requests   # Works directly

CI/CD / Automation Use (without direnv):

# GitHub Actions, Docker, scripts
pyve init --no-direnv
pyve run python --version
pyve run pytest
pyve run pip install requests

# Automation from any directory
cd /path/to/project && pyve run pytest
(cd /path/to/project && pyve run python script.py)

Full Examples:

# CI/CD: No direnv, explicit execution
pyve run python script.py
pyve run pytest tests/ -v
pyve run black .
pyve run mypy src/

# Automation: Run from outside project
PROJECT_DIR="/path/to/project"
cd "$PROJECT_DIR" && pyve run pytest tests/

Backend-Specific Behavior:

Venv backend:

# Executes directly from .venv/bin/
pyve run python script.py
# Equivalent to: .venv/bin/python script.py

Micromamba backend:

# Uses micromamba run with prefix
pyve run python script.py
# Equivalent to: micromamba run -p .pyve/envs/<name> python script.py

Error Handling:

# Command not found
pyve run nonexistent
# ERROR: Command not found in venv: nonexistent
# Exit code: 127

# No environment
pyve run python
# ERROR: No Python environment found
# ERROR: Run 'pyve init' to create an environment first

Use Cases:

  • CI/CD pipelines - Run tests without activation
  • Scripts - Execute Python scripts deterministically
  • One-off commands - Run tools without entering environment
  • Automation - Consistent execution across systems

pyve doctor - Environment Diagnostics

Check environment health and configuration:

pyve doctor

What it checks:

  • Backend type (venv or micromamba)
  • Environment location and status
  • Python version
  • Micromamba binary (if applicable)
  • Environment files (environment.yml, conda-lock.yml)
  • Lock file status (up to date, stale, missing)
  • Package count
  • Direnv configuration
  • .env file status

Example Output (Venv):

Pyve Environment Diagnostics
=============================

✓ Backend: venv
✓ Environment: .venv
✓ Python: 3.13.7
✓ Version file: .tool-versions (asdf)
  Python: 3.13.7
  Packages: 42 installed
✓ Direnv: .envrc configured
✓ Environment file: .env (configured)

Example Output (Micromamba):

Pyve Environment Diagnostics
=============================

✓ Backend: micromamba
✓ Micromamba: /Users/user/.pyve/bin/micromamba (user) v1.5.3
✓ Environment: .pyve/envs/myproject
  Name: myproject
✓ Python: 3.11.7
✓ Environment file: environment.yml
⚠ Lock file: conda-lock.yml (stale)
  environment.yml: 2026-01-06 02:15:30
  conda-lock.yml:  2026-01-05 18:42:15
  Packages: 87 installed
✓ Direnv: .envrc configured
✓ Environment file: .env (configured)

Status Indicators:

  • ✓ - Success/OK
  • ✗ - Error/Not found
  • ⚠ - Warning/Issue detected

Use Cases:

  • Debugging - Identify environment issues
  • Verification - Confirm setup is correct
  • CI/CD - Validate environment in pipelines
  • Troubleshooting - Quick health check

pyve validate — Validate Installation

Validate Pyve installation structure and version compatibility:

pyve validate

What it checks:

  • Pyve version compatibility
  • Installation structure (.pyve directory, config file)
  • Backend configuration
  • Environment existence (venv directory or micromamba environment)
  • Python version availability
  • Direnv integration (.env file)

Example Output (Success):

Pyve Installation Validation
==============================

✓ Pyve version: 1.5.2 (current)
✓ Backend: venv
✓ Virtual environment: .venv (exists)
✓ Configuration: valid
✓ Python version: 3.11 (available)
✓ direnv integration: .env (exists)

All validations passed.

Example Output (Warnings):

Pyve Installation Validation
==============================

⚠ Pyve version: 1.4.0 (current: 1.5.2)
  Migration recommended. Run 'pyve init --update' to update.
✓ Backend: venv
✗ Virtual environment: .venv (missing)
  Run 'pyve init' to create.
✓ Configuration: valid
✓ Python version: 3.11 (available)

Validation completed with warnings and errors.

Exit Codes:

  • 0 - All validations passed
  • 1 - Validation errors (missing files, invalid config)
  • 2 - Warnings only (version mismatch, migration suggested)

Use Cases:

  • Version tracking - Check if project uses current Pyve version
  • Migration - Identify projects that need updating
  • Troubleshooting - Diagnose installation issues
  • CI/CD - Validate project structure in pipelines

Smart Re-initialization

Pyve intelligently handles re-initialization of existing projects without requiring manual cleanup.

Running pyve init on existing project:

When you run pyve init on an already-initialized project, Pyve detects the existing installation and offers options:

$ pyve init
⚠ Project already initialized with Pyve
  Recorded version: 1.5.1
  Current version: 1.5.2
  Backend: venv

What would you like to do?
  1. Update in-place (preserves environment, updates config)
  2. Purge and re-initialize (clean slate)
  3. Cancel

Choose [1/2/3]:

Non-interactive Flags:

# Safe update (preserves environment)
pyve init --update

# Force re-initialization (auto-purge, prompts for confirmation)
pyve init --force

Safe Update (--update):

  • Preserves existing virtual environment
  • Updates configuration and version tracking
  • Adds missing config fields
  • Rejects backend changes (requires --force)
  • Rejects major Python version changes

Example:

$ pyve init --update
Updating existing Pyve installation...
✓ Configuration updated
  Version: 1.5.1 → 1.5.2
  Backend: venv (unchanged)

Project updated to Pyve v1.5.2

Force Re-initialization (--force):

  • Purges existing environment
  • Prompts for confirmation
  • Allows backend changes
  • Creates fresh installation

Example:

$ pyve init --force
⚠ Force re-initialization: This will purge the existing environment
  Current backend: venv

Continue? [y/N]: y

✓ Purging existing environment...
✓ Environment purged

Proceeding with fresh initialization...

Conflict Detection:

Backend changes are detected and require --force:

$ pyve init --backend micromamba --update
✗ Cannot update in-place: Backend change detected
  Current: venv
  Requested: micromamba

Backend changes require a clean re-initialization.
Run: pyve init --force

Use Cases:

  • Version migration - Update projects to newer Pyve versions
  • Configuration updates - Add new config fields safely
  • Backend switching - Change from venv to micromamba (or vice versa)
  • Project recovery - Fix corrupted installations

--no-direnv Flag - Skip Direnv Configuration

Skip .envrc creation for environments where direnv isn't available:

pyve init --no-direnv

When to use:

  • CI/CD environments - Where direnv isn't installed
  • Docker containers - Where direnv isn't needed
  • Automation scripts - Where manual activation isn't desired
  • Minimal setups - Where you prefer pyve run only

Behavior:

  • Skips .envrc file creation
  • Environment still fully functional
  • Use pyve run to execute commands
  • No direnv dependency required

Examples:

# Venv without direnv
pyve init --no-direnv
pyve run python --version

# Micromamba without direnv
pyve init --backend micromamba --no-direnv
pyve run pytest

# CI/CD setup
pyve init --backend micromamba --auto-bootstrap --no-direnv --strict
pyve run pytest tests/

CI/CD Integration

Pyve is designed for deterministic, reproducible environments in CI/CD pipelines.

GitHub Actions

Venv Backend:

name: Test with Venv
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install asdf
        uses: asdf-vm/actions/setup@v3
      
      - name: Install Python
        run: |
          asdf plugin add python
          asdf install python 3.11.7
      
      - name: Install Pyve
        run: |
          git clone https://github.com/pointmatic/pyve.git /tmp/pyve
          /tmp/pyve/pyve.sh self install
      
      - name: Initialize environment
        run: pyve init --no-direnv
      
      - name: Run tests
        run: pyve run pytest tests/
      
      - name: Check environment
        run: pyve doctor

Micromamba Backend:

name: Test with Micromamba
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Pyve
        run: |
          git clone https://github.com/pointmatic/pyve.git /tmp/pyve
          /tmp/pyve/pyve.sh self install
      
      - name: Initialize environment
        run: |
          pyve init --backend micromamba \
               --auto-bootstrap \
               --no-direnv \
               --strict
      
      - name: Run tests
        run: pyve run pytest tests/
      
      - name: Check environment
        run: pyve doctor

With Caching:

- name: Cache micromamba
  uses: actions/cache@v3
  with:
    path: ~/.pyve/bin/micromamba
    key: micromamba-${{ runner.os }}

- name: Cache environment
  uses: actions/cache@v3
  with:
    path: .pyve/envs
    key: env-${{ runner.os }}-${{ hashFiles('conda-lock.yml') }}

GitLab CI

Venv Backend:

test:
  image: ubuntu:latest
  before_script:
    - apt-get update && apt-get install -y git curl
    - git clone https://github.com/pointmatic/pyve.git /tmp/pyve
    - /tmp/pyve/pyve.sh self install
    - export PATH="$HOME/.local/bin:$PATH"
  script:
    - pyve init --no-direnv
    - pyve run pytest tests/
    - pyve doctor

Micromamba Backend:

test:
  image: ubuntu:latest
  before_script:
    - apt-get update && apt-get install -y git curl
    - git clone https://github.com/pointmatic/pyve.git /tmp/pyve
    - /tmp/pyve/pyve.sh self install
    - export PATH="$HOME/.local/bin:$PATH"
  script:
    - pyve init --backend micromamba --auto-bootstrap --no-direnv --strict
    - pyve run pytest tests/
    - pyve doctor
  cache:
    paths:
      - .pyve/envs/
      - ~/.pyve/bin/

Docker

Dockerfile with Venv:

FROM python:3.11-slim

WORKDIR /app

# Install Pyve
RUN git clone https://github.com/pointmatic/pyve.git /tmp/pyve && \
    /tmp/pyve/pyve.sh self install

# Copy project files
COPY . .

# Initialize environment
RUN pyve init --no-direnv

# Run application
CMD ["pyve", "run", "python", "app.py"]

Dockerfile with Micromamba:

FROM ubuntu:22.04

WORKDIR /app

# Install dependencies
RUN apt-get update && apt-get install -y git curl

# Install Pyve
RUN git clone https://github.com/pointmatic/pyve.git /tmp/pyve && \
    /tmp/pyve/pyve.sh self install

# Copy project files
COPY environment.yml conda-lock.yml ./

# Initialize environment
RUN pyve init --backend micromamba --auto-bootstrap --no-direnv --strict

# Copy application
COPY . .

# Run application
CMD ["pyve", "run", "python", "app.py"]

Best Practices

For CI/CD:

  1. Always use --no-direnv (direnv not needed in CI)
  2. Use --auto-bootstrap for micromamba (no interactive prompts)
  3. Use --strict to enforce lock file validation
  4. Cache environments and binaries for faster builds
  5. Run pyve doctor to verify setup
  6. Use pyve run for all command execution

Caching Strategy:

  • Cache micromamba binary (~/.pyve/bin/micromamba)
  • Cache environments (.pyve/envs/ or .venv/)
  • Use lock file hash as cache key
  • Invalidate cache when dependencies change

Example Complete Workflow:

name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Cache Pyve
        uses: actions/cache@v3
        with:
          path: |
            ~/.pyve/bin
            .pyve/envs
          key: pyve-${{ runner.os }}-${{ hashFiles('conda-lock.yml') }}
      
      - name: Install Pyve
        run: |
          git clone https://github.com/pointmatic/pyve.git /tmp/pyve
          /tmp/pyve/pyve.sh self install
      
      - name: Setup environment
        run: |
          pyve init --backend micromamba \
               --auto-bootstrap \
               --no-direnv \
               --strict
      
      - name: Verify setup
        run: pyve doctor
      
      - name: Run tests
        run: pyve run pytest tests/ --cov
      
      - name: Run linters
        run: |
          pyve run black --check .
          pyve run mypy src/

Security

  • Never commit secrets: Pyve automatically adds .env to .gitignore
  • Restricted permissions: .env files are created with chmod 600 (owner read/write only)
  • Smart purge: Non-empty .env files are preserved during purge to prevent data loss

Future Feature Ideas

  • Version management tool installation:
    • Automated installation of asdf
    • Automated installation of pyenv
    • Automated addition of Python plugin using asdf or pyenv
    • Automated installation of a Python version using either asdf or pyenv

License

Apache License 2.0 - see LICENSE file.

Copyright

Copyright (c) 2025-2026 Pointmatic (https://www.pointmatic.com)

Acknowledgments

Thanks to the asdf, pyenv, micromamba,and direnv communities for their excellent tools.

About

A focused CLI tool that simplifies setting up and managing Python virtual environments on macOS and Linux.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors