docs: def append(self, offset, timestamp, key, value, headers=None):
          """ Append message to batch.
          """
          assert not headers, "Headers not supported in v0/v1"
          # Check types
          if type(offset) != int:
              raise TypeError(offset)
          if self._magic == 0:
              timestamp = self.NO_TIMESTAMP
          elif timestamp is None:
              timestamp = int(time.time() * 1000)
          elif type(timestamp) != int:
              raise TypeError(
                  "`timestamp` should be int, but {} provided".format(
                      type(timestamp)))
          if not (key is None or
                  isinstance(key, (bytes, bytearray, memoryview))):
              raise TypeError(
                  "Not supported type for key: {}".format(type(key)))
          if not (value is None or
                  isinstance(value, (bytes, bytearray, memoryview))):
              raise TypeError(
                  "Not supported type for value: {}".format(type(value)))
  
          # Check if we have room for another message
          pos = len(self._buffer)
          size = self.size_in_bytes(offset, timestamp, key, value)
          # We always allow at least one record to be appended
          if offset != 0 and pos + size >= self._batch_size:
              return None
  
          # Allocate proper buffer length
          self._buffer.extend(bytearray(size))
  
          # Encode message
          crc = self._encode_msg(pos, offset, timestamp, key, value)
  
          return LegacyRecordMetadata(offset, crc, size, timestamp)