docs: def putfo(self, fl, remotepath, file_size=0, callback=None, confirm=True):
          """
          Copy the contents of an open file object (``fl``) to the SFTP server as
          ``remotepath``. Any exception raised by operations will be passed
          through.
  
          The SFTP operations use pipelining for speed.
  
          :param file fl: opened file or file-like object to copy
          :param str remotepath: the destination path on the SFTP server
          :param int file_size:
              optional size parameter passed to callback. If none is specified,
              size defaults to 0
          :param callable callback:
              optional callback function (form: ``func(int, int)``) that accepts
              the bytes transferred so far and the total bytes to be transferred
              (since 1.7.4)
          :param bool confirm:
              whether to do a stat() on the file afterwards to confirm the file
              size (since 1.7.7)
  
          :return:
              an `.SFTPAttributes` object containing attributes about the given
              file.
  
          .. versionadded:: 1.10
          """
          with self.file(remotepath, 'wb') as fr:
              fr.set_pipelined(True)
              size = 0
              while True:
                  data = fl.read(32768)
                  fr.write(data)
                  size += len(data)
                  if callback is not None:
                      callback(size, file_size)
                  if len(data) == 0:
                      break
          if confirm:
              s = self.stat(remotepath)
              if s.st_size != size:
                  raise IOError('size mismatch in put!  %d != %d' % (s.st_size, size))
          else:
              s = SFTPAttributes()
          return s