geoprior.utils.deps_utils#

Dependency utilities providing functions to handle package installation, checking, and ensuring that optional dependencies are available.

Functions

ensure_module_installed(module_name[, ...])

Ensure that the required module is installed, optionally installing it if missing.

ensure_pkg(name[, extra, error, ...])

Decorator to ensure a Python package is installed before function execution.

ensure_pkgs(names[, extra, error, ...])

Decorator to ensure Python packages are installed before function execution.

get_installation_name(module_name[, ...])

Determines the appropriate name for installing a package, considering potential discrepancies between the distribution name and the module import name.

get_versions([extras, distribution_mapping])

Retrieve a dictionary containing version information for common libraries, as well as any user-specified packages and distribution name mappings.

install_package(name[, dist_name, ...])

Install a Python package at runtime, optionally specifying a version constraint or other parameters, using either conda or pip.

install_pkg(name[, dist_name, ...])

Install a Python package using either conda or pip, with an option to display installation progress and fallback mechanism.

is_installing(module[, upgrade, action, ...])

Install or uninstall a module/package using the subprocess under the hood.

is_module_installed(module_name[, ...])

Check if a Python module is installed by attempting to import it.

geoprior.utils.deps_utils.ensure_pkg(name, extra='', error='raise', min_version=None, exception=None, dist_name=None, infer_dist_name=False, auto_install=False, use_conda=False, partial_check=False, condition=None, verbose=False)[source]#

Decorator to ensure a Python package is installed before function execution.

If the specified package is not installed, or if its installed version does not meet the minimum version requirement, this decorator can optionally install or upgrade the package automatically using either pip or conda.

Parameters:
  • name (str) – The name of the package.

  • extra (str, optional) – Additional specification for the package, such as version or extras.

  • error (str, optional) – Error handling strategy if the package is missing: ‘raise’, ‘ignore’, or ‘warn’.

  • min_version (str or None, optional) – The minimum required version of the package. If not met, triggers installation.

  • exception (Exception, optional) – A custom exception to raise if the package is missing and errors is ‘raise’.

  • dist_name (str, optional) – The distribution name of the package as known by package managers (e.g., pip). If provided and the module import fails, an additional check based on the distribution name is performed. This parameter is useful for packages where the distribution name differs from the importable module name.

  • infer_dist_name (bool, optional) – If True, attempt to infer the distribution name for pip installation, defaults to False.

  • auto_install (bool, optional) – Whether to automatically install the package if missing. Defaults to False.

  • use_conda (bool, optional) – Prefer conda over pip for automatic installation. Defaults to False.

  • partial_check (bool, optional) – If True, checks the existence of the package only if the condition is met. This allows for conditional package checking based on the function’s arguments or other criteria. If False, the check is always performed. Defaults to False.

  • condition (Any, optional) – A condition that determines whether to check for the package’s existence. This can be a callable that takes the same arguments as the decorated function and returns a boolean, a specific argument name to check for truthiness, or any other value that will be evaluated as a boolean. If None, the package check is performed unconditionally unless partial_check is False.

  • verbose (bool, optional) – Enable verbose output during the installation process. Defaults to False.

Returns:

A decorator that wraps functions to ensure the specified package is installed.

Return type:

Callable

Examples

>>> from geoprior.utils.deps_utils import ensure_pkg
>>> @ensure_pkg("numpy", auto_install=True)
... def use_numpy():
...     import numpy as np
...     return np.array([1, 2, 3])
>>> @ensure_pkg("pandas", min_version="1.1.0", errors="warn", use_conda=True)
... def use_pandas():
...     import pandas as pd
...     return pd.DataFrame([[1, 2], [3, 4]])
>>> @ensure_pkg("matplotlib", partial_check=True, condition=lambda x, y: x > 0)
... def plot_data(x, y):
...     import matplotlib.pyplot as plt
...     plt.plot(x, y)
...     plt.show()
>>> @ensure_pkg("skimage", partial_check=True, condition=(
...     lambda *args, **kwargs: 'method' in kwargs and kwargs['method'] == 'hog')
...     )
>>> def check_package_installed(data, method='hog', **kwargs):
...     extractor_function = None
...     if method == 'hog':
...         from skimage.feature import hog
...         extractor_function = lambda image: hog(image, **kwargs)
...     return extractor_function
geoprior.utils.deps_utils.ensure_pkgs(names, extra='', error='raise', min_versions=None, exception=None, dist_names=None, infer_dist_name=False, auto_install=False, use_conda=False, partial_check=False, condition=None, verbose=False)[source]#

Decorator to ensure Python packages are installed before function execution.

If the specified packages are not installed, or if their installed versions do not meet the minimum version requirements, this decorator can optionally install or upgrade the packages automatically using either pip or conda.

Parameters:
  • names (str or list of str) – The name(s) of the package(s). Can be a single string with package names separated by commas, or a list of package names.

  • extra (str, optional) – Additional specification for the package(s), such as version or extras.

  • error ({'raise', 'ignore', 'warn'}, optional) – Error handling strategy if a package is missing: ‘raise’, ‘ignore’, or ‘warn’. Defaults to ‘raise’.

  • min_version (str or list of str, optional) – The minimum required version(s) of the package(s). If not met, triggers installation. Can be a single version string applied to all packages or a list matching the names list.

  • exception (Exception, optional) – A custom exception to raise if a package is missing and errors is ‘raise’.

  • dist_name (str or list of str, optional) – The distribution name(s) of the package(s) as known by package managers (e.g., pip). Useful when the distribution name differs from the importable module name. Can be a single string or a list matching the names list.

  • infer_dist_name (bool, optional) – If True, attempt to infer the distribution name for pip installation. Defaults to False.

  • auto_install (bool, optional) – Whether to automatically install missing packages. Defaults to False.

  • use_conda (bool, optional) – Prefer conda over pip for automatic installation. Defaults to False.

  • partial_check (bool, optional) – If True, checks the existence of the packages only if the condition is met. Allows for conditional package checking based on the function’s arguments or other criteria. If False, the check is always performed. Defaults to False.

  • condition (Any, optional) – A condition that determines whether to check for the packages’ existence. Can be a callable that takes the same arguments as the decorated function and returns a boolean, a specific argument name to check for truthiness, or any other value that will be evaluated as a boolean. If None, the package check is performed unconditionally unless partial_check is False.

  • verbose (bool, optional) – Enable verbose output during the installation process. Defaults to False.

  • min_versions (str | list[str | None] | None)

  • dist_names (str | list[str | None] | None)

Returns:

A decorator that wraps functions to ensure the specified packages are installed.

Return type:

Callable

Examples

>>> from geoprior.utils.deps_utils import ensure_pkgs
>>> @ensure_pkgs("numpy, pandas", auto_install=True)
... def use_numpy_pandas():
...     import numpy as np
...     import pandas as pd
...     return np.array([1, 2, 3]), pd.DataFrame([[1, 2], [3, 4]])
>>> @ensure_pkgs(["matplotlib", "seaborn"], min_version=["3.0.0", "0.11.0"])
... def plot_data(x, y):
...     import matplotlib.pyplot as plt
...     import seaborn as sns
...     sns.scatterplot(x=x, y=y)
...     plt.show()
>>> @ensure_pkgs("skimage", partial_check=True, condition=(
...     lambda *args, **kwargs: 'method' in kwargs and kwargs['method'] == 'hog')
... )
... def process_image(data, method='hog', **kwargs):
...     if method == 'hog':
...         from skimage.feature import hog
...         return hog(data, **kwargs)
...     else:
...         # Other processing
...         pass
geoprior.utils.deps_utils.install_package(name, dist_name=None, infer_dist_name=False, version=None, extra='', use_conda=False, verbose=True)[source]#

Install a Python package at runtime, optionally specifying a version constraint or other parameters, using either conda or pip. If conda is unavailable or disabled, pip is used by default. The function includes a check for pre-existing installations, allowing users to skip redundant installs.

Parameters:
  • name (str) – Base name of the package to install (e.g., 'requests').

  • dist_name (str, optional) – Distribution name, if different from the import name. For example, scikit-learn’s import name sklearn differs from its distribution name 'scikit-learn'.

  • infer_dist_name (bool, optional) – If True, calls get_installation_name() to infer the distribution name automatically. Defaults to False.

  • version (str, optional) – Version string or comparator. Examples include '1.2.0' interpreted as '>=1.2.0', '==1.2.0', '<2.0', and '>=1.5.3'. If None, no version constraint is applied.

  • extra (str, optional) – Additional install specifiers or command-line flags passed to the installation command. For instance, ' --no-cache-dir' or '[extra]'. Default is ''.

  • use_conda (bool, optional) – If True, attempts installation via conda first. If conda is unavailable or fails, falls back to pip. Defaults to False.

  • verbose (bool, optional) – If True, prints detailed logs throughout the installation. Defaults to True.

Returns:

On success, the specified package is installed (or is already present). If the installer fails, raises a RuntimeError.

Return type:

None

Raises:

RuntimeError – If the installation cannot be completed using either conda or pip, or if conda is requested but unavailable.

Notes

If the package is already installed, as determined by is_module_installed(), no further action is taken. When using pip, a progress bar is displayed if tqdm is installed. For conda, no progress bar is shown because of console I/O capture limitations.

Conceptually, this function assembles an install spec of the form:

(1)#\[\text{install\_str} = \langle \text{name} \rangle + \langle \text{version\_spec} \rangle + \langle \text{extra} \rangle\]

where \(\langle \text{name} \rangle\) is the package name, \(\langle \text{version\_spec} \rangle\) is a version comparator (e.g., >=1.2.0), and \(\langle \text{extra} \rangle\) is any additional flags or arguments.

Examples

>>> from geoprior.utils.deps_utils import install_package
>>> # Install requests with no version constraint, default pip:
>>> install_package('requests', verbose=True)
>>> # Install a specific version via conda (fallback to pip if conda fails):
>>> install_package(
...     'pandas',
...     version='==1.2.0',
...     use_conda=True,
...     verbose=True
... )

See also

is_module_installed

Check whether a Python module or corresponding distribution is already installed.

get_installation_name

Infer a distribution name for the given module name when needed.

geoprior.utils.deps_utils.is_installing(module, upgrade=True, action=True, DEVNULL=False, verbose=0, **subpkws)[source]#

Install or uninstall a module/package using the subprocess under the hood.

Parameters:
  • module (str,) – the module or library name to install using Python Index Package PIP

  • upgrade (bool,) – install the lastest version of the package. default is True.

  • DEVNULL (bool,) – decline the stdoutput the message in the console

  • action (str,bool) – Action to perform. ‘install’ or ‘uninstall’ a package. default is True which means ‘intall’.

  • verbose (int, Optional) – Control the verbosity i.e output a message. High level means more messages. default is 0.

  • subpkws (dict,) – additional subprocess keywords arguments

Returns:

success – whether the package is sucessfully installed or not.

Return type:

bool

Example

>>> from gofast import is_installing
>>> is_installing(
    'tqdm', action ='install', DEVNULL=True, verbose =1)
>>> is_installing(
    'tqdm', action ='uninstall', verbose =1)
geoprior.utils.deps_utils.get_installation_name(module_name, distribution_name=None, return_bool=False)[source]#

Determines the appropriate name for installing a package, considering potential discrepancies between the distribution name and the module import name. Optionally, returns a boolean indicating if the distribution name matches the import name.

Parameters:
  • module_name (str) – The import name of the module.

  • distribution_name (str, optional) – The distribution name of the package. If None, the function attempts to infer the distribution name from the module name.

  • return_bool (bool, optional) – If True, returns a boolean indicating whether the distribution name matches the module import name. Otherwise, returns the name recommended for installation.

Returns:

Depending on return_bool, returns either a boolean indicating if the distribution name matches the module name, or the name (distribution or module) recommended for installation.

Return type:

Union[str, bool]

geoprior.utils.deps_utils.is_module_installed(module_name, distribution_name=None)[source]#

Check if a Python module is installed by attempting to import it. Optionally, a distribution name can be provided if it differs from the module name.

Parameters:
  • module_name (str) – The import name of the module to check.

  • distribution_name (str, optional) – The distribution name of the package as known by package managers (e.g., pip). If provided and the module import fails, an additional check based on the distribution name is performed. This parameter is useful for packages where the distribution name differs from the importable module name.

Returns:

True if the module can be imported or the distribution package is installed, False otherwise.

Return type:

bool

Examples

>>> is_module_installed("sklearn")
True
>>> is_module_installed("scikit-learn", "scikit-learn")
True
>>> is_module_installed("some_nonexistent_module")
False
geoprior.utils.deps_utils.import_optional_dependency(name, extra='', errors='raise', min_version=None, exception=None)[source]#

Import an optional dependency.

By default, if a dependency is missing an ImportError with a nice message will be raised. If a dependency is present, but too old, we raise.

Parameters:
  • name (str) – The module name.

  • extra (str) – Additional text to include in the ImportError message.

  • errors (str {'raise', 'warn', 'ignore'}) –

    What to do when a dependency is not found or its version is too old.

    • raise : Raise an ImportError

    • warn : Only applicable when a module’s version is to old. Warns that the version is too old and returns None

    • ignore: If the module is not installed, return None, otherwise, return the module, even if the version is too old. It’s expected that users validate the version locally when using errors="ignore" (see. io/html.py)

  • min_version (str, default None) – Specify a minimum version that is different from the global pandas minimum version required.

  • exception (callable, BaseException) – Can be your own package exception rather than ImportError

Returns:

maybe_module – The imported module, when found and the version is correct. None is returned when the package is not found and errors is False, or when the package’s version is too old and errors is 'warn'.

Return type:

Optional[ModuleType]

geoprior.utils.deps_utils.ensure_module_installed(module_name, auto_install=False, version=None, package_manager='pip', dist_name=None, extra_install_args=None)[source]#

Ensure that the required module is installed, optionally installing it if missing.

Parameters:
  • module_name (str) – The name of the module to check and install if necessary.

  • auto_install (bool, optional) – If True, automatically install the module using the specified package manager if it is not already installed (default is False).

  • version (Optional[str], optional) – Specify a version or version range for the module. For example, “>=1.0.0” or “==2.0.1”. If None, no version constraints are applied (default is None).

  • package_manager (str, optional) – The package manager to use for installation. Currently, only "pip" is supported. Future versions may support other package managers like "conda" (default is "pip").

  • dist_name (Optional[str], optional) – Sometimes the module name used for importing is different from the distribution package name. This parameter allows specifying the distribution package name (default is None).

  • extra_install_args (Optional[List[str]], optional) – A list of additional arguments to pass to the package manager during installation. For example, ["--upgrade"] to upgrade the package. If None, no extra arguments are passed (default is None).

Returns:

Returns True if the module is installed or successfully installed, False otherwise.

Return type:

bool

Raises:
  • ImportError – If the module is not installed and auto_install is False, or if the installation fails.

  • ValueError – If an unsupported package manager is specified.

Examples

>>> from geoprior.utils.deps_utils import ensure_module_installed
>>> # Ensure that 'numpy' is installed
>>> ensure_module_installed("numpy")
>>> # Ensure that 'pandas' is installed, automatically installing if missing
>>> ensure_module_installed("pandas", auto_install=True)
>>> # Ensure that 'scipy' version >=1.5.0 is installed
>>> ensure_module_installed("scipy", version=">=1.5.0", auto_install=True)
>>> # Install with additional arguments
>>> ensure_module_installed(
...     "requests",
...     auto_install=True,
...     extra_install_args=["--upgrade"]
... )

Notes

This function currently supports only "pip" as the package manager. When specifying a version, ensure that the version string is compatible with the package manager’s version specification syntax. Packages that require system-level dependencies may still need manual installation steps.

See also

subprocess

For spawning new processes.

sys

System-specific parameters and functions.

geoprior.utils.deps_utils.get_versions(extras=None, distribution_mapping=None)[source]#

Retrieve a dictionary containing version information for common libraries, as well as any user-specified packages and distribution name mappings.

Parameters:
  • extras (list of str, optional) – Additional packages for which to attempt version retrieval. By default, None, which means no extra packages beyond the defaults.

  • distribution_mapping (dict, optional) – Mapping from import-like names to actual distribution names. For example, the import name 'sklearn' corresponds to the distribution name 'scikit-learn'. Default is None, which uses a built-in mapping for scikit-learn and any user-provided dictionary overrides or additions.

Returns:

Dictionary of the form:

{
    "__version__": {
        "numpy": "1.24.2",
        "pandas": "1.5.0",
        "sklearn": "1.3.2",
        ...
    }
}

Return type:

dict

Notes

  • By default, this function attempts to retrieve versions for the following packages: ['numpy', 'pandas', 'sklearn', 'joblib', 'tensorflow', 'keras', 'torch'].

  • If a package is not installed, it is skipped (no error is raised).

  • If <distribution_mapping> is provided, it merges with the built-in mapping (for "sklearn""scikit-learn"), allowing users to specify additional name differences.

  • Python 3.8+ is recommended to ensure importlib.metadata is available.

Examples

>>> get_versions()
{
  "__version__": {
    "numpy": "1.24.2",
    "pandas": "1.5.0",
    ...
  }
}
>>> # Add custom package and distribution mapping:
>>> get_versions(
...   extras=["spacy"],
...   distribution_mapping={"spacy": "spacy-legacy"}
... )
{
  "__version__": {
    "numpy": "1.24.2",
    "pandas": "1.5.0",
    "spacy": "3.5.1"
  }
}