import importlib


def load_from_module(search_definition):
    """
    Dynamically load the module property as defined by the search parameter.

    :param str search_definition: module.path:property_name
    :raises ValueError: In case configuration is invalid
    :return *: The property searched for
    """

    try:
        module_name, property_name = search_definition.split(":")
    except:
        raise ValueError(
            'Search definition "{}" is not valid.'.format(search_definition)
        )

    try:
        module = importlib.import_module(module_name)
    except ImportError as e:
        raise ValueError(
            'Search definition "{}" is not valid. The module specified '
            "({}) was not found. Original error: {}".format(
                search_definition, module_name, str(e)
            )
        )

    if "." in property_name:
        container, attribute = property_name.split(".")
        try:
            property = getattr(getattr(module, container), attribute)
        except AttributeError:
            raise ValueError(
                'Search definition "{}" is not valid. The module does not '
                "contain the specified property.".format(search_definition)
            )
    else:
        try:
            property = getattr(module, property_name)
        except AttributeError:
            raise ValueError(
                'Search definition "{}" is not valid. The module does not '
                "contain the specified property.".format(search_definition)
            )

    return property