Checking a Python FTP connection

Leo Mizuhara picture Leo Mizuhara · Mar 2, 2013 · Viewed 16.4k times · Source

I have a FTP connection from which I am downloading many files and processing them in between. I'd like to be able to check that my FTP connection hasn't timed out in between. So the code looks something like:

conn = FTP(host='blah')
conn.connect()
for item in list_of_items:
    myfile = open('filename', 'w')
    conn.retrbinary('stuff", myfile)
    ### do some parsing ###

How can I check my FTP connection in case it timed out during the ### do some parsing ### line?

Answer

Sean Dawson picture Sean Dawson · Mar 2, 2013

Send a NOOP command. This does nothing but check that the connection is still going and if you do it periodically it can keep the connection alive.

For example:

   conn.voidcmd("NOOP")

If there is a problem with the connection then the FTP object will throw an exception. You can see from the documentation that exceptions are thrown if there is an error:

socket.error and IOError: These are raised by the socket connection and are most likely the ones you are interested in.

exception ftplib.error_reply: Exception raised when an unexpected reply is received from the server.

exception ftplib.error_temp: Exception raised when an error code signifying a temporary error (response codes in the range 400–499) is received.

exception ftplib.error_perm: Exception raised when an error code signifying a permanent error (response codes in the range 500–599) is received.

exception ftplib.error_proto: Exception raised when a reply is received from the server that does not fit the response specifications of the File Transfer Protocol, i.e. begin with a digit in the range 1–5.

Therefore you can use a try-catch block to detect the error and handle it accordingly.

For example this sample of code will catch an IOError, tell you about it and then retry the operation:

retry = True
while (retry):
    try:
        conn = FTP('blah')
        conn.connect()
        for item in list_of_items:
            myfile = open('filename', 'w')
            conn.retrbinary('stuff', myfile)   
            ### do some parsing ###

        retry = False

    except IOError as e:
        print "I/O error({0}): {1}".format(e.errno, e.strerror)
        print "Retrying..."
        retry = True