Search code examples
pythonftplib

ftplib is timing out


I'am attempting to send 5 files over to an ftp server. However, only the first 3 out of the 5 files are sent, while the last 2 are not sent.

I suspect it has to do with timing out but im not sure, as it takes around 5 minutes for the first 3 files to be transferred.

Any suggestions?

##OLD CODE

import subprocess

#ftp credentials
server='myserver.host.com'
user='[email protected]'
password='mypassword'

#logging in to ftp
proc =subprocess.Popen(['ftp -p {}'.format(server)],shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#sending username
proc.stdin.write(bytes(user+'\n',encoding='UTF-8'))
proc.stdin.flush()
#sending password
proc.stdin.write(bytes(password+'\n',encoding='UTF-8'))
proc.stdin.flush()

#name of ftp directory were files will be transferred
ftpdirectory='ftpdir'

#list of file directories to be transferred 
filestotransfer=['/home/user/Desktop/file1.csv','/home/user/Desktop/file2.csv','/home/user/Desktop/file3.csv','/home/user/Desktop/file4.csv','/home/user/Desktop/file5.csv']

#transferring files one by one
for i in filestotransfer:
    filename=i.split('/')[-1]
    syntaxx='put "{}" "/{}/{}"'.format(i,ftpdirectory,filename) #put /home/user/Desktop/file1.csv /ftpdir/file1.csv
    proc.stdin.write(bytes(syntaxx + '\n', encoding='UTF-8'))
    proc.stdin.flush()

##SOLUTION

import ftplib
import os.path


server = "myserver.host.com"
user = "[email protected]"
password = "mypassword"
ftpdirectory = "/ftpdir"

filestotransfer = [
    "/home/user/Desktop/file1.csv",
    "/home/user/Desktop/file2.csv",
    "/home/user/Desktop/file3.csv",
    "/home/user/Desktop/file4.csv",
    "/home/user/Desktop/file5.csv",
]
for i in filestotransfer:
    try:
        with ftplib.FTP(server,timeout=10) as ftp:
            print('logging in')
            ftp.login(user, password)
    
    
            with open(i, "rb") as fp:
                dest_path = os.path.join(ftpdirectory, os.path.basename(i))
                ftp.storbinary(f"STOR {dest_path}", fp)
                print('completed sending {}'.format(i))
    
            ftp.close()
            
            
    except:
        print('timedout')
        

Solution

  • As I mentioned in the comments, ftplib is a built-in module in Python.

    Your script simplifies to something like

    import ftplib
    import os.path
    import posixpath
    
    server = "myserver.host.com"
    user = "[email protected]"
    password = "mypassword"
    ftpdirectory = "/ftpdir"
    filestotransfer = [
        "/home/user/Desktop/file1.csv",
        "/home/user/Desktop/file2.csv",
        "/home/user/Desktop/file3.csv",
        "/home/user/Desktop/file4.csv",
        "/home/user/Desktop/file5.csv",
    ]
    
    with ftplib.FTP(server) as ftp:
        ftp.login(user, password)
        for filepath in filestotransfer:
            with open(filepath, "rb") as fp:
                dest_path = posixpath.join(ftpdirectory, os.path.basename(filepath))
                print(f"Transferring {filepath} to {dest_path}")
                ftp.storbinary(f"STOR {dest_path}", fp)