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

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top