ftplib callbacks not working - Python 3
Question
I have looked everywhere and cannot find a fix for this problem, ftplib storbinary callbacks. This is my first time using callbacks so it could be something stupid, I have some code which should call my function everytime 8192 bytes are uploaded I assume (that's how I think callbacks work after research).
#In main thread
def ftpcallback(intid):
ftpuploaded = transStatus[intid][3] + 8192 #transStatus[intid] equals 0 to start with
if ftpuploaded > transStatus[intid][2]: ftpuploaded = transStatus[intid][2] #Is this needed? It's supposed to just keep the value below the file size
transStatus[intid][3] = ftpuploaded
print (transStatus[intid][3]) #Always outputs 8192
print("Callback called")
#Not in main thread
#FTP and file open code
self.ftp.storbinary("STOR " + self.destname, self.f, 1, ftpcallback(self.intid)) #1 to (hopefully) spam the output more
#close FTP and file code
Whenever that is run the callback only runs once, even for a 10MB file. What am I doing wrong? Thanks in advance
Solution
A callback, as it name suggests is when you tell some piece of code (ftplib) to call you back. What you did was to call the ftpcallback
function yourself and pass it's return value (which is None
because it doesn't return
anything) to the storbinary
method.
Instead, you want to only pass the function object when calling storbinary
and let ftplib call this function for you. You don't want to call it yourself. Therefore, you need to get rid of the (...)
.
intid = self.intid
def ftpcallback():
ftpuploaded = transStatus[intid][3] + 8192 # transStatus[intid] equals 0 to start with
if ftpuploaded > transStatus[intid][2]:
ftpuploaded = transStatus[intid][2] # Is this needed? It's supposed to just keep the value below the file size
transStatus[intid][3] = ftpuploaded
print(transStatus[intid][3]) # Always outputs 8192
print("Callback called")
#FTP and file open code
self.ftp.storbinary("STOR " + self.destname, self.f, 1, ftpcallback)
The ftplib documentation doesn't say anything about callback arguments so I assume it passes no arguments to the callback when it calls it. Your ftpcallback
must therefore be callable as ftpcallback()
, i.e. without arguments. That's why I removed the intid
argument and added intid = self.intid
before the function.
Another way to do it would be to define ftpcallback
as a method (def ftpcallback(self):
) of your class and pass self.ftpcallback
to the storbinary
call. Then you could simply use self.intid
inside the method.