def first_relationship_that_matches(end_def, end_def_type, end_def_name, relationship_typedefs):
    """
    Find the first relationship type that matches the end_def number, type
    and name from the provided typedefs.

    :param str end_def: Either 'endDef1' or 'endDef2'
    :param str end_def_type: The type within the end_def.
    :param str end_def_name:
        The name of the relationship attribute applied to the end def's entity.
        (e.g. columns, table, columnLineages, query)
    :param list(dict) relationship_typedefs:
        A list of dictionaries that follow the relationship type defs.
    :raises ValueError:
        An relationship dict was not found in the provided typedefs.
    :return: The matching relationship type definition.
    :rtype: dict
    """
    output = None
    for typedef in relationship_typedefs:
        if ((end_def in typedef) and
            (typedef[end_def]["type"] == end_def_type) and
                (typedef[end_def]["name"] == end_def_name)):
            output = typedef

    if output is None:
        raise ValueError(
            "Unable to find a relationship type that matches: {endDef} "
            "with type {end_def_type} and the name {end_def_name} from "
            "the {num_defs} provided."
            .format(
                endDef=end_def, end_def_type=end_def_type,
                end_def_name=end_def_name, num_defs=len(relationship_typedefs)
            )
        )

    return output