code: def get_function_schema(
      f: Callable[..., Any],
      *,
      name: Optional[str] = None,
      description: str,
  ) -> Dict[str, Any]:
      """Get a JSON schema for a function as defined by the OpenAI API
  
      Args:
          f: The function to get the JSON schema for
          name: The name of the function
          description: The description of the function
  
      Returns:
          A JSON schema for the function
  
      Raises:
          TypeError: If the function is not annotated
  
      Examples:
          ```
          def f(a: Annotated[str, "Parameter a"], b: int = 2, c: Annotated[float, "Parameter c"] = 0.1) -> None:
              pass
  
          get_function_schema(f, description="function f")
  
          #   {'type': 'function',
          #    'function': {'description': 'function f',
          #        'name': 'f',
          #        'parameters': {'type': 'object',
          #           'properties': {'a': {'type': 'str', 'description': 'Parameter a'},
          #               'b': {'type': 'int', 'description': 'b'},
          #               'c': {'type': 'float', 'description': 'Parameter c'}},
          #           'required': ['a']}}}
              ```
  
      """
      typed_signature = get_typed_signature(f)
      required = get_required_params(typed_signature)
      default_values = get_default_values(typed_signature)
      param_annotations = get_param_annotations(typed_signature)
      return_annotation = get_typed_return_annotation(f)
      missing, unannotated_with_default = get_missing_annotations(
          typed_signature, required
      )
  
      if return_annotation is None:
          logger.warning(
              f"The return type of the function '{f.__name__}' is not annotated. Although annotating it is "
              + "optional, the function should return either a string, a subclass of 'pydantic.BaseModel'."
          )
  
      if unannotated_with_default != set():
          unannotated_with_default_s = [
              f"'{k}'" for k in sorted(unannotated_with_default)
          ]
          logger.warning(
              f"The following parameters of the function '{f.__name__}' with default values are not annotated: "
              + f"{', '.join(unannotated_with_default_s)}."
          )
  
      if missing != set():
          missing_s = [f"'{k}'" for k in sorted(missing)]
          raise TypeError(
              f"All parameters of the function '{f.__name__}' without default values must be annotated. "
              + f"The annotations are missing for the following parameters: {', '.join(missing_s)}"
          )
  
      fname = name if name else f.__name__
  
      parameters = get_parameters(
          required, param_annotations, default_values=default_values
      )
  
      function = ToolFunction(
          function=Function(
              description=description,
              name=fname,
              parameters=parameters,
          )
      )
  
      return model_dump(function)
  
imports: import functools
  import inspect
  import json
  from logging import getLogger
  from typing import Any, Callable, Dict, ForwardRef, List, Optional, Set, Tuple, Type, TypeVar, Union
  from pydantic import BaseModel, Field
  from typing_extensions import Annotated, Literal, get_args, get_origin
  from ._pydantic import JsonSchemaValue, evaluate_forwardref, model_dump, model_dump_json, type2schema
label_desc: Use image node_id 10 for calling a global function with example usage: get_function_schema(f) and returns: model_dump