Search code examples
pythonftpftplib

Show Python FTP file upload messages


I have a remote FTP server where I want to upload new firmware images. When using the Linux ftp client I can do this using put <somefile> the server then responds with status messages like:

ftp> put TS252P005.bin flash
local: TS252P005.bin remote: flash
200 PORT command successful
150 Connecting to port 40929
226-File Transfer Complete. Starting Operation:
Checking file integrity...
Updating firmware...
Result: Success
Rebooting...
421 Service not available, remote server has closed connection
38563840 bytes sent in 6.71 secs (5.4779 MB/s)
ftp>

Now I can upload the file using Python as well using ftplib:

fw_path = ....
ip = ....
user = ...
pw = ....
with open(fw_path, "rb") as f:
    with ftplib.FTP(ip) as ftp:
        ftp.login(user=user, passwd=pw)
        ftp.storbinary("stor flash", f)

But I can't see a way for me to get the status messages that I can see using the ftp utility. This is important for me because I need to check that the update actually succeeded.

How can I get this output in my Python program? I'm also willing to use a different library if ftplib can't do it.

Any help is appreciated!


Solution

  • If you want to check the response programatically, check the result of FTP.storbinary:

    print(ftp.storbinary("STOR flash", f))
    

    Though as your server actually closes the connection before even sending a complete response, the FTP.storbinary throws an exception.

    If you want to read the partial response, you will have to re-implement what the FTP.storbinary does. Like

    ftp.voidcmd('TYPE I')
    with ftp.transfercmd("STOR flash") as conn:
        while 1:
            buf = f.read(8192)
            if not buf:
                break
            conn.sendall(buf)
    line = ftp.getline()
    print(line)
    if line[3:4] == '-':
        code = line[:3]
        while 1:
            nextline = self.getline()
            print(nextline)
            if nextline[:3] == code and nextline[3:4] != '-':
                break
    

    If you want to check the response manually, enable logging using FTP.set_debuglevel.