Skip to main content

How to Check if a Package is Installed (and Install if Needed) in Python

When writing Python scripts or applications that depend on external packages, it's often useful to check if a required package is actually installed in the user's environment before attempting to import it. This prevents ModuleNotFoundError exceptions and allows for more robust error handling or even automatic installation.

This guide demonstrates common Pythonic ways to check for package installation using try...except and importlib, and optionally install the package if it's missing.

The Need: Avoiding ModuleNotFoundError

If your script includes import some_package but some_package is not installed in the active Python environment, the script will crash immediately with a ModuleNotFoundError. Checking for the package first allows you to handle this situation gracefully, perhaps by informing the user, attempting installation, or falling back to alternative functionality.

This is the most common and often considered the most Pythonic way ("Easier to Ask for Forgiveness than Permission" - EAFP). You attempt the import and handle the specific error if it fails.

Basic Check

package_name = 'requests' # Replace with the package you want to check

try:
# Attempt to import the package
__import__(package_name) # Use __import__ for dynamic name checking
# Or directly: import requests
print(f"Package '{package_name}' is installed.")
except ModuleNotFoundError:
# Handle the case where the module is not found
print(f"Package '{package_name}' is NOT installed.")
except ImportError:
# Catch potential other import errors if needed
print(f"Error importing '{package_name}', might be installed but has issues.")
  • We wrap the import statement (using __import__ here allows checking a package name stored in a variable) in a try block.
  • If the package is installed and importable, the try block completes successfully.
  • If the package is not found, Python raises a ModuleNotFoundError, which is caught by the except block.

Installing the Package if Not Found

You can extend the except block to automatically attempt installation using pip via the subprocess module.

import sys
import subprocess
import os # For DEVNULL

package_name = 'requests' # Replace with the package name (usually lowercase)

try:
__import__(package_name)
print(f"Package '{package_name}' is already installed.")
except ModuleNotFoundError:
print(f"Package '{package_name}' is NOT installed.")
print(f"Attempting to install '{package_name}' using pip...")

try:
# Get the path to the current Python executable
python_executable = sys.executable
# Run pip install command
# Use check_call to raise an error if install fails
# Use DEVNULL to suppress pip's output (optional)
subprocess.check_call(
[python_executable, '-m', 'pip', 'install', package_name],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL # Suppress errors too if desired
)
print(f"Successfully installed '{package_name}'.")
# You might want to re-attempt the import here if needed immediately,
# though sometimes restarting the script might be necessary for Python
# to fully recognize the new package path.
# __import__(package_name) # Re-try import

except subprocess.CalledProcessError as e:
print(f"Failed to install '{package_name}'. Error: {e}")
except Exception as e:
print(f"An unexpected error occurred during installation: {e}")

# Optional: Code that now assumes the package exists (might still fail if install failed)
import requests
response = requests.get('https://httpbin.org/get')
print(response.status_code)
  • sys.executable: Crucial for getting the path to the currently running Python interpreter, ensuring pip installs the package for the correct environment.
  • subprocess.check_call([...]): Executes the pip install command. It raises a CalledProcessError if the command fails (non-zero exit code).
  • stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL: Optional arguments to hide pip's installation output from your script's console. Remove them to see pip's progress and messages.

Method 2: Using importlib.util.find_spec()

This approach checks if Python's import machinery can find the specifications for a module without actually importing and executing the module's code. This can be slightly faster if the module is large or has slow import-time side effects, but it doesn't guarantee the module will import successfully later (it could be found but corrupted).

Basic Check

import importlib.util

package_name = 'numpy' # Replace with package name

# find_spec returns a ModuleSpec object if found, None otherwise
spec = importlib.util.find_spec(package_name)

if spec is None:
print(f"Package '{package_name}' is NOT installed (or cannot be found).")
else:
print(f"Package '{package_name}' is installed.")
# The spec object contains metadata if needed:
# print(f" Location: {spec.origin}")

Installing the Package if Not Found

Combine find_spec with the installation logic from Method 1.

import importlib.util
import sys
import subprocess
import os

package_name = 'matplotlib' # Replace with package name

spec = importlib.util.find_spec(package_name)

if spec is None:
print(f"Package '{package_name}' is NOT installed.")
print(f"Attempting to install '{package_name}' using pip...")
try:
python_executable = sys.executable
subprocess.check_call(
[python_executable, '-m', 'pip', 'install', package_name],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
print(f"Successfully installed '{package_name}'.")
# Re-check spec or attempt import if needed immediately
# spec = importlib.util.find_spec(package_name) # Update spec variable
except subprocess.CalledProcessError as e:
print(f"Failed to install '{package_name}'. Error: {e}")
except Exception as e:
print(f"An unexpected error occurred during installation: {e}")
else:
print(f"Package '{package_name}' is already installed.")

# Optional: Now proceed assuming it's installed (or handle failure)
if importlib.util.find_spec(package_name):
import matplotlib.pyplot as plt
# ... use matplotlib ...
else:
print("Matplotlib installation failed, can not proceed.")

Method 3: Checking via Command Line (pip show)

You can check from outside Python using the pip show command in your terminal. This doesn't involve writing Python code but is useful for manual checks or shell scripting.

# Check for 'requests' package
pip show requests
# Or use pip3, python -m pip show, etc. if needed

Example Output if INSTALLED:

Name: requests
Version: 2.28.1
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
... more info ...
Location: /path/to/your/python/site-packages
Requires: certifi, charset-normalizer, idna, urllib3
Required-by:

Example Output if NOT INSTALLED:

WARNING: Package(s) not found: requests

This confirms installation within the environment where pip is executed.

Choosing the Right Method

  • try...except ModuleNotFoundError: Generally the most Pythonic (EAFP). It directly attempts the action (importing) and handles the expected failure. It ensures the module is not only present but also basically importable (though import could still fail for other reasons).
  • importlib.util.find_spec(): Useful if you want to check for existence without executing the module's import-time code. It's slightly more complex syntactically and doesn't guarantee a successful import later. It aligns more with the "Look Before You Leap" (LBYL) style.
  • pip show: For command-line checks outside your Python script.

For most in-script checks, the try...except method is recommended for its clarity and directness.

Conclusion

Checking if a Python package is installed before use prevents ModuleNotFoundError crashes and enables more robust applications.

  1. The standard Pythonic approach is to use a try...except ModuleNotFoundError block around the import statement.
  2. An alternative is importlib.util.find_spec(), which checks if the module can be found by the import system without actually loading it.
  3. Both methods can be extended using the subprocess module to attempt automatic installation via pip if the package is missing, ensuring you use sys.executable to target the correct environment.
  4. For manual checks, use pip show <package_name> in your terminal.

Choose the method that best suits your needs, prioritizing the try...except approach for typical in-script checks.