docs: def spreadsheet2gradebook(
              self,
              csv_file,
              email_field=None,
              approve_grades=False,
              use_max_points_column=False,
              max_points_column=None,
              normalize_column=None
      ):
          """Upload grade spreadsheet to gradebook.
  
          Upload grades from CSV format spreadsheet file into the
          Learning Modules gradebook.  The spreadsheet must have a column
          named ``External email`` which is used as the student's email
          address (for looking up and matching studentId).
  
          These columns are disregarded: ``ID``, ``Username``,
          ``Full Name``, ``edX email``, ``External email``,
          as well as the strings passed in ``max_points_column``
          and ``normalize_column``, if any.
          All other columns are taken as assignments.
  
          If ``email_field`` is specified, then that field name is taken as
          the student's email.
  
          .. code-block:: none
  
              External email,AB Assignment 01,AB Assignment 02
              jeannechiang@gmail.com,1.0,0.9
              stellar.test2@gmail.com,0.2,0.4
              stellar.test1@gmail.com,0.93,0.77
  
          Args:
              csv_reader (str): filename of csv data, or readable file object
              email_field (str): student's email
              approve_grades (bool): Should grades be auto approved?
              use_max_points_column (bool):
                  If ``True``, read the max points and normalize values
                  from the CSV and use the max points value in place of
                  the default if normalized is ``False``.
              max_points_column (str): The name of the max_pts column. All
                  rows contain the same number, the max points for
                  the assignment.
              normalize_column (str): The name of the normalize column which
                  indicates whether to use the max points value.
  
          Raises:
              PyLmodFailedAssignmentCreation: Failed to create assignment
              requests.RequestException: Exception connection error
              ValueError: Unable to decode response content
  
          Returns:
              tuple: tuple of dictionary containing response ``status``
              and ``message``, and duration of operation
  
          """
          non_assignment_fields = [
              'ID', 'Username', 'Full Name', 'edX email', 'External email'
          ]
          if max_points_column is not None:
              non_assignment_fields.append(max_points_column)
          if normalize_column is not None:
              non_assignment_fields.append(normalize_column)
  
          if email_field is not None:
              non_assignment_fields.append(email_field)
          else:
              email_field = 'External email'
  
          if not hasattr(csv_file, 'read'):
              file_pointer = open(csv_file)
          else:
              file_pointer = csv_file
          csv_reader = csv.DictReader(file_pointer, dialect='excel')
  
          response = self._spreadsheet2gradebook_multi(
              csv_reader,
              email_field,
              non_assignment_fields,
              approve_grades=approve_grades,
              use_max_points_column=use_max_points_column,
              max_points_column=max_points_column,
              normalize_column=normalize_column
          )
          return response