Skip to content

extpackages

Base module to handle processing extensions as packages.

Attributes

mlogger = get_logger(__name__) module-attribute

PLUGIN_EXT_DEF_MANIFEST_NAME = 'extensions' module-attribute

PLUGIN_EXT_DEF_FILE = PLUGIN_EXT_DEF_MANIFEST_NAME + exts.JSON_FILE_FORMAT module-attribute

EXTENSION_POSTFIXES = [x.POSTFIX for x in exts.ExtensionTypes.get_ext_types()] module-attribute

Classes

PyRevitPluginAlreadyInstalledException(extpkg)

Bases: PyRevitException

Exception raised when extension is already installed.

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def __init__(self, extpkg):
    super(PyRevitPluginAlreadyInstalledException, self).__init__()
    self.extpkg = extpkg
    PyRevitException(self)

Attributes

msg property

Return exception message.

extpkg = extpkg instance-attribute

PyRevitPluginNoInstallLinkException

Bases: PyRevitException

Exception raised when extension does not have an install link.

Attributes

msg property

Return exception message.

PyRevitPluginRemoveException

Bases: PyRevitException

Exception raised when removing an extension.

Attributes

msg property

Return exception message.

DependencyGraph(extpkg_list)

Extension packages dependency graph.

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def __init__(self, extpkg_list):
    self.dep_dict = defaultdict(list)
    self.extpkgs = extpkg_list
    for extpkg in extpkg_list:
        if extpkg.dependencies:
            for dep_pkg_name in extpkg.dependencies:
                self.dep_dict[dep_pkg_name].append(extpkg)

Attributes

dep_dict = defaultdict(list) instance-attribute
extpkgs = extpkg_list instance-attribute

Functions

has_installed_dependents(extpkg_name)
Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def has_installed_dependents(self, extpkg_name):
    if extpkg_name in self.dep_dict:
        for dep_pkg in self.dep_dict[extpkg_name]:
            if dep_pkg.is_installed:
                return True
    else:
        return False

ExtensionPackage(info_dict, def_file_path=None)

Extension package class.

This class contains the extension information and also manages installation, user configuration, and removal of the extension. See the __init__ class documentation for the required and optional extension information.

Attributes:

Name Type Description
type ExtensionTypes

Extension type

name str

Extension name

description str

Extension description

url str

Url of online git repository

website str

Url of extension website

image str

Url of extension icon image (.png file)

author str

Name of extension author

author_profile str

Url of author profile

Initialized the extension class based on provide information.

Required info (Dictionary keys): type, name, description, url

Optional info

website, image, author, author-url, authusers

Parameters:

Name Type Description Default
info_dict dict

A dictionary containing the required information for initializing the extension.

required
def_file_path str

The file path of the extension definition file

None
Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def __init__(self, info_dict, def_file_path=None):
    """Initialized the extension class based on provide information.

    Required info (Dictionary keys):
        type, name, description, url

    Optional info:
        website, image, author, author-url, authusers

    Args:
        info_dict (dict): A dictionary containing the required information
                          for initializing the extension.
        def_file_path (str): The file path of the extension definition file
    """
    self.type = exts.ExtensionTypes.UI_EXTENSION
    self.builtin = False
    self.default_enabled = True
    self.name = None
    self.description = None
    self.url = None
    self.def_file_path = set()
    self.authusers = set()
    self.authgroups = set()
    self.rocket_mode_compatible = False
    self.website = None
    self.image = None
    self.author = None
    self.author_profile = None
    self.dependencies = set()

    self.update_info(info_dict, def_file_path=def_file_path)

Attributes

type = exts.ExtensionTypes.UI_EXTENSION instance-attribute
builtin = False instance-attribute
default_enabled = True instance-attribute
name = None instance-attribute
description = None instance-attribute
url = None instance-attribute
def_file_path = set() instance-attribute
authusers = set() instance-attribute
authgroups = set() instance-attribute
rocket_mode_compatible = False instance-attribute
website = None instance-attribute
image = None instance-attribute
author = None instance-attribute
author_profile = None instance-attribute
dependencies = set() instance-attribute
ext_dirname property

Installation directory name to use.

Returns:

Type Description
str

The name that should be used for the installation directory (based on the extension type).

is_installed property

Installation directory.

Returns:

Type Description
str

Installed directory path or empty string if not installed.

installed_dir property

Installation directory.

Returns:

Type Description
str

Installed directory path or empty string if not installed.

is_removable property

Whether the extension is safe to remove.

Checks whether it is safe to remove this extension by confirming if a git url is provided for this extension for later re-install.

Returns:

Type Description
bool

True if removable, False if not

version property

Extension version.

Returns:

Type Description
str

Last commit hash of the extension git repo.

config property

Returns a valid config manager for this extension.

All config parameters will be saved in user config file.

Returns:

Type Description
PyRevitConfigSectionParser

Config section handler

is_enabled property

Checks the default and user configured load state of the extension.

Returns:

Type Description
bool

True if package should be loaded

user_has_access property

Checks whether current user has access to this extension.

Returns:

Type Description
bool

True is current user has access

Functions

update_info(info_dict, def_file_path=None)
Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def update_info(self, info_dict, def_file_path=None):
    ext_def_type = info_dict.get('type', None)
    for ext_type in exts.ExtensionTypes.get_ext_types():
        if ext_def_type == ext_type.ID:
            self.type = ext_type

    self.builtin = \
        safe_strtype(info_dict.get('builtin',
                                   self.builtin)).lower() == 'true'

    self.default_enabled = safe_strtype(
        info_dict.get('default_enabled', self.default_enabled)
        ).lower() == 'true'

    self.name = info_dict.get('name', self.name)
    self.description = info_dict.get('description', self.description)
    self.url = info_dict.get('url', self.url)

    if def_file_path:
        self.def_file_path.add(def_file_path)

    # update list of authorized users
    authusers = info_dict.get('authusers', [])
    if authusers:
        self.authusers.update(authusers)

    # update list of authorized user groups
    authgroups = info_dict.get('authgroups', [])
    if authgroups:
        self.authgroups.update(authgroups)

    # rocket mode compatibility
    self.rocket_mode_compatible = \
        safe_strtype(
            info_dict.get('rocket_mode_compatible',
                          self.rocket_mode_compatible)
            ).lower() == 'true'

    # extended attributes
    self.website = info_dict.get(
        'website',
        self.url.replace('.git', '') if self.url else self.website
        )
    self.image = info_dict.get('image', self.image)
    self.author = info_dict.get('author', self.author)

    self.author_profile = info_dict.get('author_profile',
                                        self.author_profile)
    # update list dependencies
    depends = info_dict.get('dependencies', [])
    if depends:
        self.dependencies.update(depends)
is_valid()
Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def is_valid(self):
    return self.name is not None and self.url is not None
remove_pkg_config()

Removes the installed extension configuration.

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def remove_pkg_config(self):
    """Removes the installed extension configuration."""
    user_config.remove_section(self.ext_dirname)
    user_config.save_changes()
disable_package()

Disables package in pyRevit configuration.

It won't be loaded in the next session.

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def disable_package(self):
    """Disables package in pyRevit configuration.

    It won't be loaded in the next session.
    """
    self.config.disabled = True
    user_config.save_changes()
toggle_package()

Disables/Enables package in pyRevit configuration.

A disabled package won't be loaded in the next session.

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def toggle_package(self):
    """Disables/Enables package in pyRevit configuration.

    A disabled package won't be loaded in the next session.
    """
    self.config.disabled = not self.config.disabled
    user_config.save_changes()

Functions

get_ext_packages(authorized_only=True)

Returns the registered plugin extensions packages.

Reads the list of registered plug-in extensions and returns a list of ExtensionPackage classes which contain information on the plug-in extension.

Parameters:

Name Type Description Default
authorized_only bool

Only return authorized extensions

True

Returns:

Type Description
list[ExtensionPackage]

list of registered plugin extensions

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def get_ext_packages(authorized_only=True):
    """Returns the registered plugin extensions packages.

    Reads the list of registered plug-in extensions and returns a list of
    ExtensionPackage classes which contain information on the plug-in extension.

    Args:
        authorized_only (bool): Only return authorized extensions

    Returns:
        (list[ExtensionPackage]): list of registered plugin extensions
    """
    extpkgs = []
    for ext_dir in user_config.get_ext_root_dirs():
        # make a list of all availabe extension definition sources
        # default is under the extensions directory that ships with pyrevit
        extpkg_def_files = {op.join(ext_dir, PLUGIN_EXT_DEF_FILE)}
        # add other sources added by the user (using the cli)
        extpkg_def_files.update(user_config.get_ext_sources())
        for extpkg_def_file in extpkg_def_files:
            mlogger.debug('Looking for %s', extpkg_def_file)
            # check for external ext def file
            if op.exists(extpkg_def_file):
                mlogger.debug('Found %s', extpkg_def_file)
                _update_extpkgs(extpkg_def_file, extpkgs)
            # check internals now
            internal_extpkg_defs = _find_internal_extpkgs(ext_dir)
            for int_def_file in internal_extpkg_defs:
                _update_extpkgs(int_def_file, extpkgs)

    if authorized_only:
        return [x for x in extpkgs if x.user_has_access]

    return extpkgs

get_ext_package_by_name(extpkg_name)

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def get_ext_package_by_name(extpkg_name):
    for extpkg in get_ext_packages(authorized_only=False):
        if extpkg.name == extpkg_name:
            return extpkg
    return None

get_dependency_graph()

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def get_dependency_graph():
    return DependencyGraph(get_ext_packages(authorized_only=False))

install(extpkg, install_dir, install_dependencies=True)

Install the extension in the given parent directory.

This method uses .installed_dir property of extension object as installation directory name for this extension. This method also handles installation of extension dependencies.

Parameters:

Name Type Description Default
extpkg ExtensionPackage

Extension package to be installed

required
install_dir str

Parent directory to install extension in.

required
install_dependencies bool

Install the dependencies as well

True

Raises:

Type Description
PyRevitException

on install error with error message

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def install(extpkg, install_dir, install_dependencies=True):
    """Install the extension in the given parent directory.

    This method uses .installed_dir property of extension object 
    as installation directory name for this extension.
    This method also handles installation of extension dependencies.

    Args:
        extpkg (ExtensionPackage): Extension package to be installed
        install_dir (str): Parent directory to install extension in.
        install_dependencies (bool): Install the dependencies as well

    Raises:
        PyRevitException: on install error with error message
    """
    try:
        _install_extpkg(extpkg, install_dir, install_dependencies)
    except PyRevitPluginAlreadyInstalledException as already_installed_err:
        mlogger.warning('%s extension is already installed under %s',
                        already_installed_err.extpkg.name,
                        already_installed_err.extpkg.is_installed)
    except PyRevitPluginNoInstallLinkException:
        mlogger.error('Extension does not have an install link '
                      'and can not be installed.')

remove(extpkg, remove_dependencies=True)

Removes the extension.

Removes the extension from its installed directory and clears its configuration.

Parameters:

Name Type Description Default
extpkg ExtensionPackage

Extension package to be removed

required
remove_dependencies bool

Remove the dependencies as well

True

Raises:

Type Description
PyRevitException

on remove error with error message

Source code in pyrevitlib/pyrevit/extensions/extpackages.py
def remove(extpkg, remove_dependencies=True):
    """Removes the extension.

    Removes the extension from its installed directory
    and clears its configuration.

    Args:
        extpkg (ExtensionPackage): Extension package to be removed
        remove_dependencies (bool): Remove the dependencies as well

    Raises:
        PyRevitException: on remove error with error message
    """
    try:
        _remove_extpkg(extpkg, remove_dependencies)
    except PyRevitPluginRemoveException as remove_err:
        mlogger.error('Error removing extension: %s | %s',
                      extpkg.name, remove_err)