This seems to be a bug in Paramiko. See the source code for paramiko v1.12.0 and how the callback is called before checking if the transfer is already finished:
def getfo(self, remotepath, fl, callback=None):
fr = self.file(remotepath, 'rb')
file_size = self.stat(remotepath).st_size
fr.prefetch()
try:
size = 0
while True:
data = fr.read(32768)
fl.write(data)
size += len(data)
if callback is not None:
callback(size, file_size)
if len(data) == 0:
break
finally:
fr.close()
return size
In later versions this is fixed - http://www.lag.net/paramiko/docs/paramiko.sftp_client-pysrc.html
def get(self, remotepath, localpath, callback=None):
fr = self.file(remotepath, 'rb')
file_size = self.stat(remotepath).st_size
fr.prefetch()
try:
fl = file(localpath, 'wb')
try:
size = 0
while True:
data = fr.read(32768)
if len(data) == 0:
break
fl.write(data)
size += len(data)
if callback is not None:
callback(size, file_size)
finally:
fl.close()
finally:
fr.close()
See the difference -
if len(data) == 0:
break
is called before the callback in the latter. So you have to either get a newer version of Paramiko, or to live with the bug... Or maybe to use a patch for Paramiko code :)