How do I upload full directory on FTP in python?
Question: Ok, so I have to upload a directory, with subdirectories and files inside, on
a FTP server. But I can't seem to get it right. I want to upload the directory
as it is, with it's subdirectories and files where they were.

    
    
    ftp = FTP()
    ftp.connect('host',port)
    ftp.login('user','pass')
    filenameCV = "directorypath"
    
    def placeFiles():
    
     for root,dirnames,filenames in os.walk(filenameCV):
        for files in filenames:
            print(files)
            ftp.storbinary('STOR ' + files, open(files,'rb'))
            ftp.quit()
    
    placeFiles()
    


Answer: There are multiple problems with your code: First, the `filenames` array will
only contain the actual filenames, not the entire path, so you need to join it
with `fullpath = os.path.join(root, files)` and then use `open(fullpath)`.
Secondly, you quit the FTP connection inside the loop, move that `ftp.quit()`
down on the level of the `placeFiles()` function.

To recursively upload your directory, you have to walk through your root
directories and at the same time through your remote directory, uploading
files on the go.

Full example code:

    
    
    import os.path, os
    from ftplib import FTP, error_perm
    
    host = 'localhost'
    port = 21
    
    ftp = FTP()
    ftp.connect(host,port)
    ftp.login('user','pass')
    filenameCV = "directorypath"
    
    def placeFiles(ftp, path):
        for name in os.listdir(path):
            localpath = os.path.join(path, name)
            if os.path.isfile(localpath):
                print("STOR", name, localpath)
                ftp.storbinary('STOR ' + name, open(localpath,'rb'))
            elif os.path.isdir(localpath):
                print("MKD", name)
    
                try:
                    ftp.mkd(name)
    
                # ignore "directory already exists"
                except error_perm as e:
                    if not e.args[0].startswith('550'): 
                        raise
    
                print("CWD", name)
                ftp.cwd(name)
                placeFiles(ftp, localpath)           
                print("CWD", "..")
                ftp.cwd("..")
    
    placeFiles(ftp, filenameCV)
    
    ftp.quit()
    

