def get_call_signature(fn: FunctionType,
                       args: ArgsType,
                       kwargs: KwargsType,
                       debug_cache: bool = False) -> str:
    """
    Takes a function and its args/kwargs, and produces a string description
    of the function call (the call signature) suitable for use indirectly as a
    cache key. The string is a JSON representation. See ``make_cache_key`` for
    a more suitable actual cache key.
    """
    # Note that the function won't have the __self__ argument (as in
    # fn.__self__), at this point, even if it's a member function.
    try:
        call_sig = json_encode((fn.__qualname__, args, kwargs))
    except TypeError:
        log.critical(
            "\nTo decorate using @django_cache_function without specifying "
            "cache_key, the decorated function's owning class and its "
            "parameters must be JSON-serializable (see jsonfunc.py, "
            "django_cache_fn.py).\n")
        raise
    if debug_cache:
        log.debug("Making call signature {!r}", call_sig)
    return call_sig
Takes a function and its args/kwargs, and produces a string description
    of the function call (the call signature) suitable for use indirectly as a
    cache key. The string is a JSON representation. See ``make_cache_key`` for
    a more suitable actual cache key.