def get_function_params(func: Callable) -> list[tuple[str, bool, Any, Any]]:
    """
    Gets the parameters of a function as a list of tuples of the form (name, has_default, default_value, type_hint).
    Excludes *args and **kwargs, as well as args that are Gradio-specific, such as gr.Request, gr.EventData, gr.OAuthProfile, and gr.OAuthToken.
    """
    params_info = []
    try:
        signature = inspect.signature(func)
    except ValueError:
        signature = inspect.Signature()
    type_hints = get_type_hints(func)
    for name, parameter in signature.parameters.items():
        if parameter.kind in (
            inspect.Parameter.VAR_POSITIONAL,
            inspect.Parameter.VAR_KEYWORD,
        ):
            break
        if is_special_typed_parameter(name, type_hints):
            continue
        if parameter.default is inspect.Parameter.empty:
            params_info.append((name, False, None, type_hints.get(name, None)))
        else:
            params_info.append(
                (name, True, parameter.default, type_hints.get(name, None))
            )
    return params_info

    Gets the parameters of a function as a list of tuples of the form (name, has_default, default_value, type_hint).
    Excludes *args and **kwargs, as well as args that are Gradio-specific, such as gr.Request, gr.EventData, gr.OAuthProfile, and gr.OAuthToken.
    
gradio/utils.py