def is_boundary_type(reaction, boundary_type, external_compartment):
<EOL>sbo_term = reaction.annotation.get("<STR_LIT>", "<STR_LIT>")<EOL>if isinstance(sbo_term, list):<EOL><INDENT>sbo_term = sbo_term[<NUM_LIT:0>]<EOL><DEDENT>sbo_term = sbo_term.upper()<EOL>if sbo_term == sbo_terms[boundary_type]:<EOL><INDENT>return True<EOL><DEDENT>if sbo_term in [sbo_terms[k] for k in sbo_terms if k != boundary_type]:<EOL><INDENT>return False<EOL><DEDENT>correct_compartment = external_compartment in reaction.compartments<EOL>if boundary_type != "<STR_LIT>":<EOL><INDENT>correct_compartment = not correct_compartment<EOL><DEDENT>rev_type = True<EOL>if boundary_type == "<STR_LIT>":<EOL><INDENT>rev_type = not reaction.reversibility<EOL><DEDENT>elif boundary_type == "<STR_LIT>":<EOL><INDENT>rev_type = reaction.reversibility<EOL><DEDENT>return (reaction.boundary and not<EOL>any(ex in reaction.id for ex in excludes[boundary_type]) and<EOL>correct_compartment and rev_type)<EOL>
Check whether a reaction is an exchange reaction.

    Arguments
    ---------
    reaction : cobra.Reaction
        The reaction to check.
    boundary_type : str
        What boundary type to check for. Must be one of
        "exchange", "demand", or "sink".
    external_compartment : str
        The id for the external compartment.

    Returns
    -------
    boolean
        Whether the reaction looks like the requested type. Might be based
        on a heuristic.