Example #1
0
def load_node_class(type_string):
    """
    Return the `Node` sub class that corresponds to the given type string.

    :param type_string: the `type` string of the node
    :return: a sub class of `Node`
    """
    from aiida.orm import Data, Node
    from aiida.plugins.entry_point import load_entry_point

    if type_string == '':
        return Node

    if type_string == 'data.Data.':
        return Data

    if not type_string.endswith('.'):
        raise exceptions.DbContentError('The type string `{}` is invalid'.format(type_string))

    try:
        base_path = type_string.rsplit('.', 2)[0]
    except ValueError:
        raise exceptions.EntryPointError

    # This exception needs to be there to make migrations work that rely on the old type string starting with `node.`
    # Since now the type strings no longer have that prefix, we simply strip it and continue with the normal logic.
    if base_path.startswith('node.'):
        base_path = strip_prefix(base_path, 'node.')

    # Data nodes are the only ones with sub classes that are still external, so if the plugin is not available
    # we fall back on the base node type
    if base_path.startswith('data.'):
        entry_point_name = strip_prefix(base_path, 'data.')
        try:
            return load_entry_point('aiida.data', entry_point_name)
        except exceptions.MissingEntryPointError:
            return Data

    if base_path.startswith('process'):
        entry_point_name = strip_prefix(base_path, 'nodes.')
        return load_entry_point('aiida.node', entry_point_name)

    # At this point we really have an anomalous type string. At some point, storing nodes with unresolvable type strings
    # was allowed, for example by creating a sub class in a shell and then storing an instance. Attempting to load the
    # node then would fail miserably. This is now no longer allowed, but we need a fallback for existing cases, which
    # should be rare. We fallback on `Data` and not `Node` because bare node instances are also not storable and so the
    # logic of the ORM is not well defined for a loaded instance of the base `Node` class.
    warnings.warn('unknown type string `{}`, falling back onto `Data` class'.format(type_string))  # pylint: disable=no-member

    return Data
Example #2
0
    def get_metadata(self):
        """
        Get the metadata dictionary from the DB

        :return: a dictionary
        """
        import json

        try:
            return json.loads(self._dbauthinfo.metadata)
        except ValueError:
            raise exceptions.DbContentError(
                "Error while reading metadata for dbauthinfo, aiidauser={}, computer={}"
                .format(self.aiidauser.email, self.dbcomputer.hostname))
Example #3
0
    def get_auth_params(self):
        """
        Get the auth_params dictionary from the DB

        :return: a dictionary
        """
        try:
            return json.loads(self._dbauthinfo.auth_params)
        except ValueError:
            email = self._dbauthinfo.aiidauser.email
            hostname = self._dbauthinfo.dbcomputer.hostname
            raise exceptions.DbContentError(
                "Error while reading auth_params for dbauthinfo, aiidauser={}, computer={}"
                .format(email, hostname))
Example #4
0
def load_node_class(type_string):
    """
    Return the `Node` sub class that corresponds to the given type string.

    :param type_string: the `type` string of the node
    :return: a sub class of `Node`
    """
    from aiida.orm import Data, Node
    from aiida.plugins.entry_point import load_entry_point

    if type_string == '':
        return Node

    if type_string == 'data.Data.':
        return Data

    if not type_string.endswith('.'):
        raise exceptions.DbContentError(
            'The type string `{}` is invalid'.format(type_string))

    try:
        base_path = type_string.rsplit('.', 2)[0]
    except ValueError:
        raise exceptions.EntryPointError

    # This exception needs to be there to make migrations work that rely on the old type string starting with `node.`
    # Since now the type strings no longer have that prefix, we simply strip it and continue with the normal logic.
    if base_path.startswith('node.'):
        base_path = strip_prefix(base_path, 'node.')

    # Data nodes are the only ones with sub classes that are still external, so if the plugin is not available
    # we fall back on the base node type
    if base_path.startswith('data.'):
        entry_point_name = strip_prefix(base_path, 'data.')
        try:
            return load_entry_point('aiida.data', entry_point_name)
        except exceptions.MissingEntryPointError:
            return Data

    if base_path.startswith('process'):
        entry_point_name = strip_prefix(base_path, 'nodes.')
        return load_entry_point('aiida.node', entry_point_name)

    raise exceptions.EntryPointError(
        'unknown type string {}'.format(type_string))
Example #5
0
def is_valid_node_type_string(type_string, raise_on_false=False):
    """
    Checks whether type string of a Node is valid.

    :param type_string: the plugin_type_string attribute of a Node
    :return: True if type string is valid, else false
    """
    # Currently the type string for the top-level node is empty.
    # Change this when a consistent type string hierarchy is introduced.
    if type_string == '':
        return True

    # Note: this allows for the user-defined type strings like 'group' in the QueryBuilder
    # as well as the usual type strings like 'data.parameter.ParameterData.'
    if type_string.count('.') == 1 or not type_string.endswith('.'):
        if raise_on_false:
            raise exceptions.DbContentError('The type string {} is invalid'.format(type_string))
        return False

    return True