0
def download(self):
    ftp = self.connect()
    try:
        size = ftp.size(filename=self.filename)
        print "Total size of {filename} is {size}".format(filename=self.filename, size=size)
        written_till_now = 0
        def handle(bytes):
            f.write(bytes)
            print "written bytes: {}".format(bytes)

        with open(self.filename, 'wb') as f:
            ftp.retrbinary('RETR {}'.format(self.filename), handle)
    except (socket.error, error_perm) as e:
        raise DownloaderException("Error in downloading file {filename}: {message}".format(filename=self.filename, message=str(e)))
    except EOFError as e:
        print "file {filename} downloaded successfully".format(filename=self.filename)

I want to keep track of the amount of data i've currently downloaded and later do some additional stuff also for every stream of data i download.

I created a handle function inside the download function.

Python ftblip.retrbinary provides the data to the given callback. In my case handle but somehow it is not executing.

Also I doubt i am not understanding the scope of variables when it comes to nested functions. In my understanding I can use variable defined in parent scope in the child scope as long as i am not modifying them.But in this case f is a object and i am not modifying it rather calling its method write. Please correct me if i am missing something.

8
  • it doesn't from outside too. Commented Oct 30, 2017 at 12:43
  • I am putting it insie because later i will build a progressbar which will take. so the variable written_till_now i will access and increment Commented Oct 30, 2017 at 12:45
  • I think its because i am not even getting a single byte. It throws exception o connection refused after a while. Commented Oct 30, 2017 at 12:45
  • 2
    I would put it inside the with block because you are using f variable which is defined there. Commented Oct 30, 2017 at 12:48
  • are you able to get a successful ftp connection ? try to print something before and after ftp = self.connect() , if not this might help Commented Oct 30, 2017 at 12:52

1 Answer 1

1

The handle function doesn't have access to the scoped f variable. Instead you can pass the open file directly to handle.

def handle(fp, bytes):
    fp.write(bytes)
    print "written bytes: {}".format(bytes)

with open(self.filename, 'wb') as f:
    ftp.retrbinary('RETR {}'.format(self.filename), lambda b: handle(f, b))
Sign up to request clarification or add additional context in comments.

2 Comments

lambda b: means that the ftp will use the b variable ?
It means that the callback function takes a single argument, which we call b.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.