Skip to Content
Course content

280: Working with FTP via ftplib

Click on the "Edit" button in the top corner of the screen to edit your slide content.

How do I actually get connected and see what's on the server?

The ftplib module is a bit old-school, but it's the standard way to handle FTP in Python. To get started, you'll use the FTP class. I always recommend using a with statement or ensuring you call .quit() at the end; otherwise, you'll leave orphaned connections hanging on the server, which can eventually lead to you being blocked.

from ftplib import FTP

# Let's say we're connecting to a legacy company server
with FTP('ftp.example.com') as ftp:
    ftp.login(user='engineer_bob', passwd='secure_password123')
    
    # nlst() gives you a list of file names in the current directory
    files = ftp.nlst()
    print(f"I found these files: {files}")

One thing to watch out for: nlst() is great for a quick list, but if you need file sizes or modification dates, you'll want to use ftp.dir() or ftp.mlsd(). The latter returns a generator of tuples, which is much easier to parse programmatically than the raw string dir() spits out.

How do I upload a file without corrupting the data?

This is where most people trip up. FTP has two modes: ASCII and Binary. If you're uploading a text file, ASCII is fine. But if you're uploading an image, a PDF, or a ZIP file, you must use binary mode. If you don't, the FTP server might try to "help" you by converting line endings, which will effectively corrupt your file.

I've spent way too many hours debugging "corrupt images" only to realize I used the wrong method. Use storbinary for anything that isn't plain text.

with FTP('ftp.example.com') as ftp:
    ftp.login(user='engineer_bob', passwd='secure_password123')
    
    filename = 'site_logo.png'
    with open(filename, 'rb') as f:
        # 'STOR' is the FTP command to store a file
        # We pass the file object directly to storbinary
        ftp.storbinary(f'STOR {filename}', f)
    
    print(f"{filename} uploaded successfully.")

What's the cleanest way to download a file to my local machine?

Downloading is the mirror image of uploading. You use retrbinary. The tricky part here is that retrbinary requires a callback function to handle the chunks of data as they arrive. The easiest way to handle this is to open a local file in write-binary mode and pass its .write method as the callback.

with FTP('ftp.example.com') as ftp:
    ftp.login(user='engineer_bob', passwd='secure_password123')
    
    remote_file = 'server_logs_october.txt'
    local_file = 'logs_backup.txt'
    
    with open(local_file, 'wb') as f:
        # 'RETR' is the command to retrieve a file
        ftp.retrbinary(f'RETR {remote_file}', f.write)
        
    print(f"Downloaded {remote_file} to {local_file}")

Is there a more secure way than sending passwords in plain text?

Standard FTP is terrifying from a security perspective because everything—including your password—is sent in cleartext. If you're working on a professional project, you should almost always be using FTPS (FTP over TLS). Python handles this via FTP_TLS.

The main difference is that you call prot_p() after logging in. This tells the server to encrypt the data channel, not just the command channel. If you forget this step, your login is encrypted, but the actual files you transfer are still sent in the clear.

from ftplib import FTP_TLS

with FTP_TLS('ftp.example.com') as ftps:
    ftps.login(user='engineer_bob', passwd='secure_password123')
    ftps.prot_p()  # Switch to private data connection (encrypted)
    
    # Now you can safely list or transfer files
    print(ftps.nlst())



📋 Practical Task

Exercise: Automated Website Asset Backup Script

You need to build a utility script that automates the backup of image assets from a remote FTP server to a local folder. Write a Python script that performs the following steps:

  • Connects to an FTP server (you can use a mock server or a test account).
  • Logs in using provided credentials.
  • Retrieves a list of all files in the remote directory.
  • Filters that list to find only files ending in .jpg or .png.
  • Downloads each of those images into a local directory named /backups/.
  • Ensures the connection is closed properly regardless of whether the downloads succeeded or failed.

Requirement: Use retrbinary for the downloads to ensure the images aren't corrupted during the transfer.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.