Beta_K
Beta_K

Reputation: 67

How do I upload full directory on FTP in python?

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"

for root,dirnames,filenames in os.walk(filenameCV):
    for files in filenames:
        print(files)
        ftp.storbinary('STOR ' + files, open(files,'rb'))
        ftp.quit()

Upvotes: 4

Views: 16862

Answers (1)

jojonas
jojonas

Reputation: 1675

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()

Upvotes: 18

Related Questions