Check if a python module exists with specific venv path

If I have a venv path, how can I find out if a Python module is installed inside that venv?

I normally use importlib.util.find_spec. But this only works for the current venv that is active and does not work if I have a different venv path.

from importlib.util import find_spec

if find_spec('numpy'):
    # Do something

Approach 1: Check the venv’s site-packages Directory

Each venv has a site-packages directory where installed modules live. You can check if a module’s folder or .py file exists there.

import os
from pathlib import Path

def is_module_installed_in_venv(venv_path, module_name):
    # Convert venv_path to Path object for easier handling
    venv_path = Path(venv_path)
    
    # Determine the site-packages path based on the OS and Python version
    # Example: venv/lib/python3.11/site-packages on Unix, venv/Lib/site-packages on Windows
    python_version = "python3.11"  # Adjust this based on your venv's Python version
    site_packages = venv_path / "lib" / python_version / "site-packages"  # Unix/Mac
    if os.name == "nt":  # Windows
        site_packages = venv_path / "Lib" / "site-packages"

    if not site_packages.exists():
        return False

    # Check for module directory or .py file
    module_dir = site_packages / module_name
    module_file = site_packages / f"{module_name}.py"
    module_egg = site_packages / f"{module_name}.egg-link"  # For editable installs

    return module_dir.exists() or module_file.exists() or module_egg.exists()

# Example usage
venv_path = "/path/to/your/venv"  # Replace with your venv path
module_name = "numpy"

if is_module_installed_in_venv(venv_path, module_name):
    print(f"{module_name} is installed in {venv_path}")
else:
    print(f"{module_name} is not installed in {venv_path}")

Approach 2: Use the venv’s Python Interpreter

A more robust way is to run a Python command using the venv’s interpreter and check if the module can be imported. This leverages the venv’s own environment.

import subprocess
import os

def is_module_installed_in_venv(venv_path, module_name):
    # Path to the Python executable in the venv
    if os.name == "nt":  # Windows
        python_exe = os.path.join(venv_path, "Scripts", "python.exe")
    else:  # Unix/Mac
        python_exe = os.path.join(venv_path, "bin", "python")

    if not os.path.exists(python_exe):
        raise FileNotFoundError(f"Python executable not found in {venv_path}")

    # Run a small Python script to check for the module
    check_script = f"import importlib.util; print(1 if importlib.util.find_spec('{module_name}') else 0)"
    result = subprocess.run(
        [python_exe, "-c", check_script],
        capture_output=True,
        text=True
    )

    # Check the output: 1 means module exists, 0 means it doesn’t
    return result.stdout.strip() == "1"

# Example usage
venv_path = "/path/to/your/venv"  # Replace with your venv path
module_name = "numpy"

try:
    if is_module_installed_in_venv(venv_path, module_name):
        print(f"{module_name} is installed in {venv_path}")
    else:
        print(f"{module_name} is not installed in {venv_path}")
except FileNotFoundError as e:
    print(e)