def complete(self, _, incomplete): """Return possible completions based on an incomplete value. :returns: list of tuples of valid entry points (matching incomplete) and a description """ from aiida.plugins.entry_point import get_entry_point_names entry_points = get_entry_point_names('aiida.groups') return [ (ep, '') for ep in entry_points if (ep.startswith('pseudo.family') and ep.startswith(incomplete)) ]
def _load_error_handlers(self): """Load the error handlers defined through entry points, if any.""" if self._error_handler_entry_point is not None: for entry_point_name in get_entry_point_names(self._error_handler_entry_point): try: load_entry_point(self._error_handler_entry_point, entry_point_name) self.logger.info("loaded the '%s' entry point for the '%s' error handlers category", entry_point_name, self._error_handler_entry_point) except exceptions.EntryPointError as exception: self.logger.warning("failed to load the '%s' entry point for the '%s' error handlers: %s", entry_point_name, self._error_handler_entry_point, exception)
def _load_error_handlers(self): """If an error handler entry point is defined, load them. If the plugin cannot be loaded log it and pass.""" if self._error_handler_entry_point is not None: for entry_point_name in get_entry_point_names(self._error_handler_entry_point): try: load_entry_point(self._error_handler_entry_point, entry_point_name) self.logger.info("loaded the '%s' entry point for the '%s' error handlers category", entry_point_name, self._error_handler_entry_point) except exceptions.EntryPointError as exception: self.logger.warning("failed to load the '%s' entry point for the '%s' error handlers: %s", entry_point_name, self._error_handler_entry_point, exception)
def get_valid_transports(cls): """Return the list of registered transport entry points. .. deprecated:: 1.4.0 Will be removed in `2.0.0`, use `aiida.plugins.entry_point.get_entry_point_names` instead """ import warnings from aiida.common.warnings import AiidaDeprecationWarning from aiida.plugins.entry_point import get_entry_point_names message = 'method is deprecated, use `aiida.plugins.entry_point.get_entry_point_names` instead' warnings.warn(message, AiidaDeprecationWarning) # pylint: disable=no-member return get_entry_point_names('aiida.transports')
def verdi_config_caching(disabled): """List caching-enabled process types for the current profile.""" from aiida.plugins.entry_point import ENTRY_POINT_STRING_SEPARATOR, get_entry_point_names from aiida.manage.caching import get_use_cache for group in ['aiida.calculations', 'aiida.workflows']: for entry_point in get_entry_point_names(group): identifier = ENTRY_POINT_STRING_SEPARATOR.join([group, entry_point]) if get_use_cache(identifier=identifier): if not disabled: echo.echo(identifier) elif disabled: echo.echo(identifier)
def get_valid_schedulers(cls): """Return all available scheduler plugins. .. deprecated:: 1.3.0 Will be removed in `2.0.0`, use `aiida.plugins.entry_point.get_entry_point_names` instead """ import warnings from aiida.common.warnings import AiidaDeprecationWarning from aiida.plugins.entry_point import get_entry_point_names message = 'method is deprecated, use `aiida.plugins.entry_point.get_entry_point_names` instead' warnings.warn(message, AiidaDeprecationWarning) # pylint: disable=no-member return get_entry_point_names('aiida.schedulers')
def plugin_list(entry_point_group, entry_point): """Display a list of all available plugins.""" from aiida.common import EntryPointError from aiida.cmdline.utils.common import print_process_info from aiida.engine import Process from aiida.plugins.entry_point import get_entry_point_names, load_entry_point if entry_point_group is None: echo.echo_info('Available entry point groups:') for group in sorted(ENTRY_POINT_GROUP_TO_MODULE_PATH_MAP.keys()): echo.echo('* {}'.format(group)) echo.echo('') echo.echo_info( 'Pass one of the groups as an additional argument to show the registered plugins' ) return if entry_point: try: plugin = load_entry_point(entry_point_group, entry_point) except EntryPointError as exception: echo.echo_critical(str(exception)) else: try: if (inspect.isclass(plugin) and issubclass( plugin, Process)) or plugin.is_process_function: print_process_info(plugin) else: echo.echo(str(plugin.get_description())) except AttributeError: echo.echo_error( 'No description available for {}'.format(entry_point)) else: entry_points = get_entry_point_names(entry_point_group) if entry_points: echo.echo( 'Registered entry points for {}:'.format(entry_point_group)) for registered_entry_point in entry_points: echo.echo('* {}'.format(registered_entry_point)) echo.echo('') echo.echo_info( 'Pass the entry point as an argument to display detailed information' ) else: echo.echo_error( 'No plugins found for group {}'.format(entry_point_group))
def get_all_download_formats(full_type=None): """ returns dict of possible node formats for all available node types """ from aiida.plugins.entry_point import load_entry_point, get_entry_point_names from aiida.restapi.common.identifiers import load_entry_point_from_full_type, construct_full_type from aiida.common import EntryPointError from aiida.common.exceptions import LoadingEntryPointError from aiida.restapi.common.exceptions import RestFeatureNotAvailable, RestInputValidationError all_formats = {} if full_type: try: node_cls = load_entry_point_from_full_type(full_type) except (TypeError, ValueError): raise RestInputValidationError( 'The full type {} is invalid.'.format(full_type)) except EntryPointError: raise RestFeatureNotAvailable( 'The download formats for this node type are not available.' ) try: available_formats = node_cls.get_export_formats() all_formats[full_type] = available_formats except AttributeError: pass else: entry_point_group = 'aiida.data' for name in get_entry_point_names(entry_point_group): try: node_cls = load_entry_point(entry_point_group, name) except LoadingEntryPointError: pass else: node_cls.get_export_formats() try: available_formats = node_cls.get_export_formats() if available_formats: full_type = construct_full_type( node_cls.class_node_type, '') all_formats[full_type] = available_formats except AttributeError: pass return all_formats
def _load_error_handlers(self): # If an error handler entry point is defined, load them. If the plugin cannot be loaded log it and pass if self._error_handler_entry_point is not None: for entry_point_name in get_entry_point_names( self._error_handler_entry_point): try: load_entry_point(self._error_handler_entry_point, entry_point_name) self.logger.info( "loaded the '{}' entry point for the '{}' error handlers category" .format(entry_point_name, self._error_handler_entry_point, plugin)) except EntryPointError as exception: self.logger.warning( "failed to load the '{}' entry point for the '{}' error handlers: '{}'" .format(entry_point_name, self._error_handler_entry_point, exception))
def get_workflow_entry_point_names(workflow: str, leaf: bool = False) -> typing.List[str]: """Return the registered entry point names for the given common workflow. :param workflow: the name of the common workflow. :param leaf: if True, only return the leaf of the entry point name, i.e., the name of plugin that implements it. :return: list of entry points names. """ prefix = f'{PACKAGE_PREFIX}.{workflow}.' entry_points_names = entry_point.get_entry_point_names('aiida.workflows') if not leaf: return [name for name in entry_points_names if name.startswith(prefix)] return [ name[len(prefix):] for name in entry_points_names if name.startswith(prefix) ]
def test_installed(self): """ Return wether the plugin is installed First, this checks wether the package_name can be imported. If not, we know that at least no new style plugin with that name is installed. Secondly, tests wether all the entry points are currently found by the plugin loader. If not, it is considered not installed. potential failures: * loading of the entry points is not tested * not properly uninstalled plugins might show up as installed if the entry points are still around. * it does not distinguish between not installed and an old version is installed """ from importlib import import_module from pkg_resources import get_distribution new_style = False installed = True iversion = None try: import_module(self.package_name) new_style = True iversion = get_distribution(self.package_name).version except ImportError: new_style = False from aiida.plugins.entry_point import get_entry_point_names if iversion == self.version or not new_style: for cat, ep in self.entry_points.iteritems(): if not set(ep).issubset( set(get_entry_point_names('aiida.' + cat))): installed = False return installed, new_style, iversion
def potential_list(entry_point, schema_depth): """Display a list of all available plugins.""" entry_point_group = "gulp.potentials" if entry_point: try: plugin = load_entry_point(entry_point_group, entry_point) except EntryPointError as exception: echo.echo_critical(str(exception)) else: try: echo.echo(str(plugin.get_description()), bold=True) except (AttributeError, TypeError): echo.echo_error( "No description available for {}".format(entry_point)) try: schema = plugin.get_schema() echo.echo("Data Schema:") edict.pprint(schema, depth=schema_depth, print_func=echo.echo, keycolor="blue") except (AttributeError, TypeError): echo.echo_error("No validation schema available for {}".format( entry_point)) else: entry_points = get_entry_point_names(entry_point_group) if entry_points: echo.echo( "Registered entry points for {}:".format(entry_point_group)) for registered_entry_point in entry_points: echo.echo("* {}".format(registered_entry_point)) echo.echo("") echo.echo_info( "Pass the entry point as an argument to display detailed information" ) else: echo.echo_error( "No plugins found for group {}".format(entry_point_group))
def get_all_download_formats(full_type=None): """ returns dict of possible node formats for all available node types """ all_formats = {} if full_type: try: node_cls = load_entry_point_from_full_type(full_type) except (TypeError, ValueError): raise RestInputValidationError( f'The full type {full_type} is invalid.') except EntryPointError: raise RestFeatureNotAvailable( 'The download formats for this node type are not available.' ) try: available_formats = node_cls.get_export_formats() all_formats[full_type] = available_formats except AttributeError: pass else: entry_point_group = 'aiida.data' for name in get_entry_point_names(entry_point_group): try: node_cls = load_entry_point(entry_point_group, name) available_formats = node_cls.get_export_formats() except (AttributeError, LoadingEntryPointError): continue if available_formats: full_type = construct_full_type(node_cls.class_node_type, '') all_formats[full_type] = available_formats return all_formats
def list_commands(self, ctx): """Add entry point names of available plugins to the command list.""" subcommands = super(Pluginable, self).list_commands(ctx) subcommands.extend(get_entry_point_names(self._entry_point_group)) return subcommands
def list_types(cls): return get_entry_point_names(cls.entry_name)
def get_valid_schedulers(cls): from aiida.plugins.entry_point import get_entry_point_names return get_entry_point_names('aiida.schedulers')
def __init__(self, path_to_root="../", **kwargs): style = {"description_width": "200px"} # Code label. inp_label = ipw.Text( description="AiiDA code label:", layout=ipw.Layout(width="500px"), style=style, ) link((inp_label, "value"), (self, "label")) # Computer on which the code is installed. Two dlinks are needed to make sure we get a Computer instance. self.inp_computer = ComputerDropdown( path_to_root=path_to_root, layout={"margin": "0px 0px 0px 125px"}) dlink((self, "computer"), (self.inp_computer, "selected_computer")) # Code plugin. self.inp_code_plugin = ipw.Dropdown( options=sorted(get_entry_point_names("aiida.calculations")), description="Code plugin:", layout=ipw.Layout(width="500px"), style=style, ) link((self.inp_code_plugin, "value"), (self, "input_plugin")) # Code description. inp_description = ipw.Text( placeholder="No description (yet)", description="Code description:", layout=ipw.Layout(width="500px"), style=style, ) link((inp_description, "value"), (self, "description")) inp_abs_path = ipw.Text( placeholder="/path/to/executable", description="Absolute path to executable:", layout=ipw.Layout(width="500px"), style=style, ) link((inp_abs_path, "value"), (self, "remote_abs_path")) inp_prepend_text = ipw.Textarea( placeholder="Text to prepend to each command execution", description="Prepend text:", layout=ipw.Layout(width="400px"), ) link((inp_prepend_text, "value"), (self, "prepend_text")) inp_append_text = ipw.Textarea( placeholder="Text to append to each command execution", description="Append text:", layout=ipw.Layout(width="400px"), ) link((inp_append_text, "value"), (self, "append_text")) btn_setup_code = ipw.Button(description="Setup code") btn_setup_code.on_click(self._setup_code) self._setup_code_out = ipw.Output() children = [ ipw.HBox([ ipw.VBox([ inp_label, self.inp_computer, self.inp_code_plugin, inp_description, inp_abs_path, ]), ipw.VBox([inp_prepend_text, inp_append_text]), ]), btn_setup_code, self._setup_code_out, ] super().__init__(children, **kwargs)
return None @strawberry.field(name=f"{name}s") def multiple(self, info) -> typing.List[data_class]: q = QueryBuilder() q.append(orm_class, project=["*"]) return [data_class.from_orm(entry) for entry in q.iterall()] setattr(cls, name, single) setattr(cls, f"{name}s", multiple) # PoC for looking up dataclasses on plugins and loading them dynamically # Limited to aiida.data subclasses/entry point for now ep_group_name = "aiida.data" entry_points = get_entry_point_names(ep_group_name) for registered_entry_point in entry_points: try: # Limit to the ones in our internal registry. # Could also be provided by the plugin or as part of the ORM class # Another option would be to look at the schema added for the REST API # but sometimes that doesn't give the access and it would be a bit more involved # to recover the typing information from that. adc = DC_REGISTRY[registered_entry_point] except KeyError: continue print( f"-> Loading dataclass for {ep_group_name}.{registered_entry_point}, to be registered as {registered_entry_point}" ) cls = load_entry_point(ep_group_name, registered_entry_point)
# -*- coding: utf-8 -*- """Test the automatic 'invalidates_cache' attribute for exit codes.""" import inspect import pytest from aiida.engine import CalcJob from aiida.plugins import CalculationFactory from aiida.plugins.entry_point import get_entry_point_names QE_CALC_ENTRY_POINT_NAMES = [ ep_name for ep_name in get_entry_point_names(group='aiida.calculations') if ep_name.startswith('quantumespresso') ] # When explicitly overriden 'invalidates_cache' are added, add entries # EXPLICIT_OVERRIDES = {<entry_point_name>: [<status_integer>, ...]} EXPLICIT_OVERRIDES = {} @pytest.mark.parametrize('entry_point_name', QE_CALC_ENTRY_POINT_NAMES) def test_exit_code_invalidates_cache(entry_point_name): """Test automatic 'invalidates_cache' attribute of exit codes. Test that the 'invalidates_cache' attribute of exit codes is automatically set according to the status integer. """ entry_point = CalculationFactory(entry_point_name) if not inspect.isclass(entry_point) or not issubclass( entry_point, CalcJob):
def list_pair_styles(cls): return get_entry_point_names(cls.entry_name)