# Tutorial: FTP Uploads with Python

> URL: https://www.atlantic.net/dedicated-server-hosting/how-to-ftp-uploads-python/ | Published: 2016-01-18 | Updated: 2025-11-03 | Author: Alexander Wise

## Introduction

In [another article on using `ftplib` in Python](https://www.atlantic.net/hipaa-compliant-hosting/how-to-ftp-python-basics/), we talked about using Python’s `ftplib` library to connect to an FTP server and download both binary and text files to our local machine. In this segment, I’ll introduce several new concepts, including uploading text and binary files, error handling, and common directory commands using the same imported library..

## FTP Uploads

As with downloads, you’ll need to specify whether a file you wish to upload to a server is a text file or a binary file since each uses a different method. You can upload text files using the `storlines()` method and binary files with the `storbinary()` method. A nice feature of these functions is that neither one requires you to write a separate function to handle reading the source file: `storlines()` calls the `readline()` method on each line in the file until it reads the last line, while `storbinary()` uses the `read()` method until there is no more data to read and upload.

Once you have access to an FTP server, open a text editor and enter the following Python script:

```
from ftplib import FTP  
ftp = FTP('_your_server_address_')  
ftp.login('_username_', '_password_')  
with open('myfile.py', 'r') as f:  
    ftp.storbinary('STOR %s' % 'remotefile.py', f)  
ftp.quit()
```

This should have the effect of copying *myfile.py* from your local directory to the remote directory on your FTP server. Should you want to copy a text file instead, the script should look something like this:

```
from ftplib import FTP  
ftp = FTP('_your_server_address_')  
ftp.login('_username_', '_password_')  
with open('myfile.txt', 'r') as f:  
    ftp.storlines('STOR %s' % 'remotefile.txt', f)  
ftp.quit().
```

## Working with Directories

Like any good FTP client, the `ftplib` library supports file deletion, renaming, moving, and even directory creation and deletion. These can be somewhat obscure calls since they’re not used very often, but they are very straightforward.

Like most library calls, you can experiment with these using an interactive Python prompt, rather than a complete, standalone script. To get a demonstration, connect to your FTP server:

```
>>> from ftplib import FTP  
>>> ftp = FTP('_your_server_address_')  
>>> ftp.login('_your_username_', '_your_password_')
```

Now you should be logged in, and you can experiment with some of the following library calls:

- `delete(_filename_)` will delete a file from the server.
- `rename(_old filename_, _new filename_)` will **rename** a file in the same directory, or **move** a file to a new directory, if you specify a new path in the second argument. For instance, `rename ('spam.txt', 'eggs.txt')` will rename the file *spam.txt*, but `rename('spam.txt', 'new_directory/spam.txt')` will move *spam.txt* into the *new_directory* within the present directory.
- `mkd(_directory_)` will create a new directory.
- `rmd(_directory_)` will attempt to remove a directory. Bear in mind that most FTP file servers require that a directory be empty (even of hidden files) before it can be deleted.

It is also possible to recursively “walk” through a directory, to go into all of the subdirectories and download (or print) all of the files you come across. Unfortunately, there is no elegant way to do this. The best way is to test whether each file you come across is a directory; if you can enter it, then you use the `cwd(_directory name_)` command to enter and test each file inside. You can use the `nlist()` command to return a list of all files in the current directory, and then try to enter each one.

We can probably best illustrate this behavior with a small script. In your text editor, enter the following:

```
# Thanks to _Foundations of Python Network Programming_  
# for the following code:  
import os  
import sys  
from ftplib import FTP  
def enter_dir(f, path):  
    original_dir = f.pwd()  
    try:  
        f.cwd(path)  
    except:  
        return  
    print path  
    names = f.nlst()  
    for name in names:  
        enter_dir(f, path + '/' + name)  
    f.cwd(original_dir)  
f = FTP('ftp.kernel.org')  
f.login()  
enter_dir(f, '/pub/linux/kernel/Historic/old-versions')  
f.quit()
```

This script recursively walks through the directories on the server, printing out all of the directory names it finds as it goes. If you’d like to test this code on your local server, simply substitute *localhost* for *ftp.kernel.org* and your home directory for */pub/linux/kernel/Historic/old-versions* and run the code again. You’d also need to update `f.login()` to include your username and password as well, most likely. As long as the FTP server is running on your local machine, you should get a listing of subdirectories in your home directory..

## Error Handling With the FTP library

Like most Python libraries and modules, `ftplib` will raise an exception if an error occurs during processing. It has a list of its own errors (`ftplib.error_reply`, for instance, when an unexpected error is received from the server), and it also raises the standard `socket.error` and `IOError`. If you’re used to using `try/except` clauses, `ftplib` will be second nature to you. If you’d like to see what error is generated, the following template could prove useful:

```
try:  
    ftp._some_Python_method_call_()
except ftplib.all_errors, e:  
    errorcode_string = str(e)  
    print errorcode_string.
```

## Conclusion

I hope these short introductions to Python’s `ftplib` library have shown how useful it can be. There are plenty more method calls available, and I highly recommend you check out [the online Python documentation](https://docs.python.org/2/library/ftplib.html). Thank you for reading! Be sure to check back for more updates, and to learn more about our [dedicated server hosting](https://www.atlantic.net/dedicated-server-hosting/) solutions.
 .
 .
