def get_api_info(self, all_endpoints: bool = False) -> APIInfo:
        """
        Gets the information needed to generate the API docs from a Blocks.
        Parameters:
            all_endpoints: If True, returns information about all endpoints, including those with show_api=False.
        """
        config = self.config
        api_info: APIInfo = {"named_endpoints": {}, "unnamed_endpoints": {}}

        for fn in self.fns.values():
            if not fn.fn or fn.api_name is False:
                continue
            if not all_endpoints and not fn.show_api:
                continue

            dependency_info: APIEndpointInfo = {
                "parameters": [],
                "returns": [],
                "show_api": fn.show_api,
            }
            fn_info = utils.get_function_params(fn.fn)  # type: ignore
            description, _, _ = utils.get_function_description(fn.fn)
            if description:
                dependency_info["description"] = description
            skip_endpoint = False

            inputs = fn.inputs
            for index, input_block in enumerate(inputs):
                for component in config["components"]:
                    if component["id"] == input_block._id:
                        break
                else:
                    skip_endpoint = True  # if component not found, skip endpoint
                    break
                type = component["props"]["name"]
                if self.blocks[component["id"]].skip_api:
                    continue
                label = component["props"].get("label", f"parameter_{input_block._id}")
                comp = self.get_component(component["id"])
                if not isinstance(comp, components.Component):
                    raise TypeError(f"{comp!r} is not a Component")
                info = component.get("api_info_as_input", component.get("api_info"))
                example = comp.example_inputs()
                python_type = client_utils.json_schema_to_python_type(info)

                # Since the clients use "api_name" and "fn_index" to designate the endpoint and
                # "result_callbacks" to specify the callbacks, we need to make sure that no parameters
                # have those names. Hence the final checks.
                if (
                    fn.fn
                    and index < len(fn_info)
                    and fn_info[index][0]
                    not in ["api_name", "fn_index", "result_callbacks"]
                ):
                    parameter_name = fn_info[index][0]
                else:
                    parameter_name = f"param_{index}"

                # How default values are set for the client: if a component has an initial value, then that parameter
                # is optional in the client and the initial value from the config is used as default in the client.
                # If the component does not have an initial value, but if the corresponding argument in the predict function has
                # a default value of None, then that parameter is also optional in the client and the None is used as default in the client.
                if component["props"].get("value") is not None:
                    parameter_has_default = True
                    parameter_default = component["props"]["value"]
                elif (
                    fn.fn
                    and index < len(fn_info)
                    and fn_info[index][1]
                    and fn_info[index][2] is None
                ):
                    parameter_has_default = True
                    parameter_default = None
                else:
                    parameter_has_default = False
                    parameter_default = None

                dependency_info["parameters"].append(
                    {
                        "label": label,
                        "parameter_name": parameter_name,
                        "parameter_has_default": parameter_has_default,
                        "parameter_default": parameter_default,
                        "type": info,
                        "python_type": {
                            "type": python_type,
                            "description": info.get("additional_description", ""),
                        },
                        "component": type.capitalize(),
                        "example_input": example,
                    }
                )

            outputs = fn.outputs
            for o in outputs:
                for component in config["components"]:
                    if component["id"] == o._id:
                        break
                else:
                    skip_endpoint = True  # if component not found, skip endpoint
                    break
                type = component["props"]["name"]
                if self.blocks[component["id"]].skip_api:
                    continue
                label = component["props"].get("label", f"value_{o._id}")
                comp = self.get_component(component["id"])
                if not isinstance(comp, components.Component):
                    raise TypeError(f"{comp!r} is not a Component")
                info = component.get("api_info_as_output", component["api_info"])
                example = comp.example_inputs()
                python_type = client_utils.json_schema_to_python_type(info)
                dependency_info["returns"].append(
                    {
                        "label": label,
                        "type": info,
                        "python_type": {
                            "type": python_type,
                            "description": info.get("description", ""),
                        },
                        "component": type.capitalize(),
                    }
                )

            if not skip_endpoint:
                api_info["named_endpoints"][f"/{fn.api_name}"] = dependency_info

        return api_info

        Gets the information needed to generate the API docs from a Blocks.
        Parameters:
            all_endpoints: If True, returns information about all endpoints, including those with show_api=False.
        
gradio/blocks.py