Reputation: 18252
I'm using the sftp module of paramiko to transfer payloads to remote hosts. Part of the sftp.put
call allows for specifying a callback method with signature func(int,int)
. I'm trying to put a transfer stats method into my Connection
class to keep track of payload progress.
Here's the class I have currently:
class Connection:
def __init__(self, endpoint, RSAKeyObj):
self.displayHost = bcolors.OKGREEN + endpoint + bcolors.ENDC
self.transport = paramiko.Transport((endpoint,4022))
self.transport.connect(username='transit', pkey=RSAKeyObj)
self.sftp = paramiko.SFTPClient.from_transport(self.transport)
try:
# initial sftp directory setup
log.info('[{0}]: Setting up remote directories...'.format(self.displayHost))
log.info(self.sftp.mkdir(JAIL_DIR))
except:
pass
def static_vars(**kwargs):
def decorate(func):
for k in kwargs:
setattr(func, k, kwargs[k])
return func
return decorate
@static_vars(counter=0)
def TransferStats(self, transferedBytes, totalBytes):
if (transferedBytes / totalBytes) >= TransferStats.counter:
log.info('Transferred: {}% [{}/{}]'.format(round((transferedBytes/totalBytes)*100,2), transferedBytes, totalBytes))
TransferStats.counter += 0.025
def Transmit(self,targetDir, payloadPath):
displayText = 'Transferring package {}...'.format(payloadPath)
self.TransferStats().counter=0
log.info('[%s] ' % self.displayHost + displayText)
log.info(self.sftp.put(payloadPath, '%s/%s' % (targetDir,payloadPath), callback=self.TransferStats()))
However when I try this, I get the following error:
ERROR - (, TypeError('TransferStats() takes exactly 3 arguments (1 given)',), )
This makes me think that the callback isn't getting recognized by paramiko when it tries to send it's (int,int)
because of the self
declaration. Is there a way around this?
Upvotes: 0
Views: 677
Reputation: 6203
Your problem is in :
log.info(self.sftp.put(payloadPath, '%s/%s' % (targetDir,payloadPath), callback=self.TransferStats()))
Your error :
ERROR - (, TypeError('TransferStats() takes exactly 3 arguments (1 given)',), )
Is caused by calling TransferStats
with no arguments (self.TransferStats()
will result in 1 argument : the class (as it is a class method))
Just pass the classmethod:
log.info(self.sftp.put(payloadPath, '%s/%s' % (targetDir,payloadPath), callback=self.TransferStats))
EDIT : You have the same problem in the following line :
self.TransferStats().counter=0
Remove the parentheses :
self.TransferStats.counter=0
Also, your counter
attribute on TransferStats
is a hidden a global, resetted at each Transmit
call.
Upvotes: 2