def get_function_signature(func_name, abi):
    """
    Given a function name and an ABI, return the function signature
    e.g. get_function_signature("tokenURI", abi) => "tokenURI(uint256)(string)"

    :param func_name:
    :type func_name: str
    :param abi:
    :type abi: list
    :return: function signature
    :rtype: str
    """
    filtered = list(
        filter(
            lambda d: d["name"] == func_name if d["type"] == "function" else None, abi
        )
    )[0]
    input_types = [obj["type"] for obj in filtered["inputs"]]
    output_types = [obj["type"] for obj in filtered["outputs"]]
    return f"{func_name}({','.join(input_types)})({','.join(output_types)})"