code: def add_docstring(
      buffer,
      node,
      header,
      prepend_extras=(),
      append_extras=(),
      return_type=None,
  ):
      """
      Write docstring for a compound datatype node
  
      Parameters
      ----------
      buffer : StringIO
          Buffer to write to
      node : PlotlyNode
          Compound datatype plotly node for which to write docstring
      header :
          Top-level header for docstring that will preceded the input node's
          own description. Header should be < 71 characters long
      prepend_extras :
          List or tuple of propery name / description pairs that should be
          included at the beginning of the docstring
      append_extras :
          List or tuple of propery name / description pairs that should be
          included at the end of the docstring
      return_type :
          The docstring return type
      Returns
      -------
  
      """
      # Validate inputs
      # ---------------
      assert node.is_compound
  
      # Build wrapped description
      # -------------------------
      node_description = node.description
      if node_description:
          description_lines = textwrap.wrap(
              node_description,
              width=79 - 8,
              initial_indent=" " * 8,
              subsequent_indent=" " * 8,
          )
  
          node_description = "\n".join(description_lines) + "\n\n"
  
      # Write header and description
      # ----------------------------
      buffer.write(
          f"""
          \"\"\"
          {header}
  
  {node_description}        Parameters
          ----------"""
      )
  
      # Write parameter descriptions
      # ----------------------------
      # Write any prepend extras
      for p, v in prepend_extras:
          v_wrapped = "\n".join(
              textwrap.wrap(
                  v,
                  width=79 - 12,
                  initial_indent=" " * 12,
                  subsequent_indent=" " * 12,
              )
          )
          buffer.write(
              f"""
          {p}
  {v_wrapped}"""
          )
  
      # Write core docstring
      buffer.write(node.get_constructor_params_docstring(indent=8))
  
      # Write any append extras
      for p, v in append_extras:
          if "\n" in v:
              # If v contains newlines then assume it's already wrapped as
              # desired
              v_wrapped = v
          else:
              v_wrapped = "\n".join(
                  textwrap.wrap(
                      v,
                      width=79 - 12,
                      initial_indent=" " * 12,
                      subsequent_indent=" " * 12,
                  )
              )
          buffer.write(
              f"""
          {p}
  {v_wrapped}"""
          )
  
      # Write return block and close docstring
      # --------------------------------------
      buffer.write(
          f"""
  
          Returns
          -------
          {return_type}
          \"\"\""""
      )
  
file_path: plotly.py/packages/python/plotly/codegen/datatypes.py
imports: import os.path
  import textwrap
  from io import StringIO
  from codegen.utils import PlotlyNode, write_source_py
label_desc: Use image node_id 5 for calling a global function with example usage: add_docstring(buffer, node, header, prepend_extras, append_extras, return_type) without return types