Skip to content

sessionmgr

The loader module manages the workflow of loading a new pyRevit session.

Its main purpose is to orchestrate the process of finding pyRevit extensions, creating dll assemblies for them, and creating a user interface in the host application.

Everything starts from sessionmgr.load_session() function...

The only public function is load_session() that loads a new session. Everything else is private.

Attributes

mlogger = logger.get_logger(__name__) module-attribute

AssembledExtension = namedtuple('AssembledExtension', ['ext', 'assm']) module-attribute

pyrevit_extcmdtype_cache = [] module-attribute

Classes

PyRevitExternalCommandType(extcmd_type, extcmd_availtype)

Bases: object

PyRevit external command type.

Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def __init__(self, extcmd_type, extcmd_availtype):
    self._extcmd_type = extcmd_type
    self._extcmd = extcmd_type()
    if extcmd_availtype:
        self._extcmd_availtype = extcmd_availtype
        self._extcmd_avail = extcmd_availtype()
    else:
        self._extcmd_availtype = None
        self._extcmd_avail = None

Attributes

extcmd_type property
typename property
extcmd_availtype property
avail_typename property
script property
config_script property
search_paths property
arguments property
engine_cfgs property
helpsource property
tooltip property
name property
bundle property
extension property
unique_id property

Functions

is_available(category_set, zerodoc=False)
Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def is_available(self, category_set, zerodoc=False):
    if self._extcmd_availtype:
        return self._extcmd_avail.IsCommandAvailable(HOST_APP.uiapp,
                                                     category_set)
    elif not zerodoc:
        return True

    return False

Functions

load_session()

Handles loading/reloading of the pyRevit addin and extensions.

To create a proper ui, pyRevit extensions needs to be properly parsed and a dll assembly needs to be created. This function handles these tasks through interactions with .extensions, .loader.asmmaker, and .loader.uimaker.

Examples:

from pyrevit.loader.sessionmgr import load_session
load_session()     # start loading a new pyRevit session

Returns:

Type Description
str

sesion uuid

Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def load_session():
    """Handles loading/reloading of the pyRevit addin and extensions.

    To create a proper ui, pyRevit extensions needs to be properly parsed and
    a dll assembly needs to be created. This function handles these tasks
    through interactions with .extensions, .loader.asmmaker, and .loader.uimaker.

    Examples:
        ```python
        from pyrevit.loader.sessionmgr import load_session
        load_session()     # start loading a new pyRevit session
        ```

    Returns:
        (str): sesion uuid
    """
    # setup runtime environment variables
    sessioninfo.setup_runtime_vars()

    # the loader dll addon, does not create an output window
    # if an output window is not provided, create one
    if EXEC_PARAMS.first_load:
        output_window = _setup_output()
    else:
        from pyrevit import script
        output_window = script.get_output()

    # initialize timer to measure load time
    timer = Timer()

    # perform pre-load tasks
    _perform_onsessionloadstart_ops()

    # create a new session
    _new_session()

    # perform post-load tasks
    _perform_onsessionloadcomplete_ops()

    # log load time and thumbs-up :)
    endtime = timer.get_time()
    success_emoji = ':OK_hand:' if endtime < 3.00 else ':thumbs_up:'
    mlogger.info('Load time: %s seconds %s', endtime, success_emoji)

    # if everything went well, self destruct
    try:
        timeout = user_config.startuplog_timeout
        if timeout > 0 and not logger.loggers_have_errors():
            if EXEC_PARAMS.first_load:
                # output_window is of type ScriptConsole
                output_window.SelfDestructTimer(timeout)
            else:
                # output_window is of type PyRevitOutputWindow
                output_window.self_destruct(timeout)
    except Exception as imp_err:
        mlogger.error('Error setting up self_destruct on output window | %s',
                      imp_err)

    _cleanup_output()
    return sessioninfo.get_session_uuid()

reload_pyrevit()

Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def reload_pyrevit():
    _perform_onsessionreload_ops()
    mlogger.info('Reloading....')
    session_Id = load_session()
    _perform_onsessionreloadcomplete_ops()
    return session_Id

find_all_commands(category_set=None, cache=True)

Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def find_all_commands(category_set=None, cache=True):
    global pyrevit_extcmdtype_cache    #pylint: disable=W0603
    if cache and pyrevit_extcmdtype_cache:    #pylint: disable=E0601
        pyrevit_extcmds = pyrevit_extcmdtype_cache
    else:
        pyrevit_extcmds = []
        for loaded_assm_name in sessioninfo.get_loaded_pyrevit_assemblies():
            loaded_assm = assmutils.find_loaded_asm(loaded_assm_name)
            if loaded_assm:
                all_exported_types = loaded_assm[0].GetTypes()

                for pyrvt_type in all_exported_types:
                    tname = pyrvt_type.FullName
                    availtname = pyrvt_type.Name \
                                 + runtime.CMD_AVAIL_NAME_POSTFIX
                    pyrvt_availtype = None

                    if not tname.endswith(runtime.CMD_AVAIL_NAME_POSTFIX)\
                            and runtime.RUNTIME_NAMESPACE not in tname:
                        for exported_type in all_exported_types:
                            if exported_type.Name == availtname:
                                pyrvt_availtype = exported_type

                        pyrevit_extcmds.append(
                            PyRevitExternalCommandType(pyrvt_type,
                                                       pyrvt_availtype)
                            )
        if cache:
            pyrevit_extcmdtype_cache = pyrevit_extcmds

    # now check commands in current context if requested
    if category_set:
        return [x for x in pyrevit_extcmds
                if x.is_available(category_set=category_set,
                                  zerodoc=HOST_APP.uidoc is None)]
    else:
        return pyrevit_extcmds

find_all_available_commands(use_current_context=True, cache=True)

Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def find_all_available_commands(use_current_context=True, cache=True):
    if use_current_context:
        cset = revit.get_selection_category_set()
    else:
        cset = None

    return find_all_commands(category_set=cset, cache=cache)

find_pyrevitcmd(pyrevitcmd_unique_id)

Find a pyRevit command.

Searches the pyRevit-generated assemblies under current session for the command with the matching unique name (class name) and returns the command type. Notice that this returned value is a 'type' and should be instantiated before use.

Examples:

cmd = find_pyrevitcmd('pyRevitCorepyRevitpyRevittoolsReload')
command_instance = cmd()
command_instance.Execute() # Provide commandData, message, elements

Parameters:

Name Type Description Default
pyrevitcmd_unique_id str

Unique name for the command

required

Returns:

Type Description
type

Type for the command with matching unique name

Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def find_pyrevitcmd(pyrevitcmd_unique_id):
    """Find a pyRevit command.

    Searches the pyRevit-generated assemblies under current session for
    the command with the matching unique name (class name) and returns the
    command type. Notice that this returned value is a 'type' and should be
    instantiated before use.

    Examples:
        ```python
        cmd = find_pyrevitcmd('pyRevitCorepyRevitpyRevittoolsReload')
        command_instance = cmd()
        command_instance.Execute() # Provide commandData, message, elements
        ```

    Args:
        pyrevitcmd_unique_id (str): Unique name for the command

    Returns:
        (type):Type for the command with matching unique name
    """
    # go through assmebles loaded under current pyRevit session
    # and try to find the command
    mlogger.debug('Searching for pyrevit command: %s', pyrevitcmd_unique_id)
    for loaded_assm_name in sessioninfo.get_loaded_pyrevit_assemblies():
        mlogger.debug('Expecting assm: %s', loaded_assm_name)
        loaded_assm = assmutils.find_loaded_asm(loaded_assm_name)
        if loaded_assm:
            mlogger.debug('Found assm: %s', loaded_assm_name)
            for pyrvt_type in loaded_assm[0].GetTypes():
                mlogger.debug('Found Type: %s', pyrvt_type)
                if pyrvt_type.FullName == pyrevitcmd_unique_id:
                    mlogger.debug('Found pyRevit command in %s',
                                  loaded_assm_name)
                    return pyrvt_type
            mlogger.debug('Could not find pyRevit command.')
        else:
            mlogger.debug('Can not find assm: %s', loaded_assm_name)

    return None

create_tmp_commanddata()

Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def create_tmp_commanddata():
    tmp_cmd_data = \
        framework.FormatterServices.GetUninitializedObject(
            UI.ExternalCommandData
            )
    tmp_cmd_data.Application = HOST_APP.uiapp
    # tmp_cmd_data.IsReadOnly = False
    # tmp_cmd_data.View = None
    # tmp_cmd_data.JournalData = None
    return tmp_cmd_data

execute_command_cls(extcmd_type, arguments=None, config_mode=False, exec_from_ui=False)

Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def execute_command_cls(extcmd_type, arguments=None,
                        config_mode=False, exec_from_ui=False):

    command_instance = extcmd_type()
    # pass the arguments to the instance
    if arguments:
        command_instance.ScriptRuntimeConfigs.Arguments = \
            framework.List[str](arguments)
    # this is a manual execution from python code and not by user
    command_instance.ExecConfigs.MimicExecFromUI = exec_from_ui
    # force using the config script
    command_instance.ExecConfigs.UseConfigScript = config_mode

    # Execute(
    # ExternalCommandData commandData,
    # string message,
    # ElementSet elements
    # )
    re = command_instance.Execute(create_tmp_commanddata(),
                                  '',
                                  DB.ElementSet())
    command_instance = None
    return re

execute_command(pyrevitcmd_unique_id)

Executes a pyRevit command.

Parameters:

Name Type Description Default
pyrevitcmd_unique_id str

Unique/Class Name of the pyRevit command

required
Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def execute_command(pyrevitcmd_unique_id):
    """Executes a pyRevit command.

    Args:
        pyrevitcmd_unique_id (str): Unique/Class Name of the pyRevit command
    """
    cmd_class = find_pyrevitcmd(pyrevitcmd_unique_id)

    if not cmd_class:
        mlogger.error('Can not find command with unique name: %s',
                      pyrevitcmd_unique_id)
        return None
    else:
        execute_command_cls(cmd_class)

execute_extension_startup_script(script_path, ext_name, sys_paths=None)

Executes a script using pyRevit script executor.

Parameters:

Name Type Description Default
script_path str

Address of the script file

required
ext_name str

Name of the extension

required
sys_paths list

additional search paths

None
Source code in pyrevitlib/pyrevit/loader/sessionmgr.py
def execute_extension_startup_script(script_path, ext_name, sys_paths=None):
    """Executes a script using pyRevit script executor.

    Args:
        script_path (str): Address of the script file
        ext_name (str): Name of the extension
        sys_paths (list): additional search paths
    """
    core_syspaths = [MAIN_LIB_DIR, MISC_LIB_DIR]
    if sys_paths:
        sys_paths.extend(core_syspaths)
    else:
        sys_paths = core_syspaths

    script_data = runtime.types.ScriptData()
    script_data.ScriptPath = script_path
    script_data.ConfigScriptPath = None
    script_data.CommandUniqueId = ''
    script_data.CommandName = 'Starting {}'.format(ext_name)
    script_data.CommandBundle = ''
    script_data.CommandExtension = ext_name
    script_data.HelpSource = ''

    script_runtime_cfg = runtime.types.ScriptRuntimeConfigs()
    script_runtime_cfg.CommandData = create_tmp_commanddata()
    script_runtime_cfg.SelectedElements = None
    script_runtime_cfg.SearchPaths = framework.List[str](sys_paths or [])
    script_runtime_cfg.Arguments = framework.List[str]([])
    script_runtime_cfg.EngineConfigs = \
        runtime.create_ipyengine_configs(
            clean=True,
            full_frame=True,
            persistent=True,
        )
    script_runtime_cfg.RefreshEngine = False
    script_runtime_cfg.ConfigMode = False
    script_runtime_cfg.DebugMode = False
    script_runtime_cfg.ExecutedFromUI = False

    runtime.types.ScriptExecutor.ExecuteScript(
        script_data,
        script_runtime_cfg
    )