2 min read

FTP File Downloader

This utility connects to an FTP server to list directory contents and download files. It uses the standard ftplib module, which implements the client side of the FTP protocol.

Modules Used:

  • ftplib: To handle FTP connections and data transfer.
  • argparse: To handle command-line arguments.
  • os: To handle local file paths.

The Code

Save this as ftp_tool.py.

import ftplib
import argparse
import os
import sys

def ftp_client(host, user, password, remote_dir, file_to_download):
    ftp = None
    try:
        # 1. Connect and Login
        print(f"Connecting to {host}...")
        ftp = ftplib.FTP(host)
        ftp.login(user, password)
        print(f"Logged in as {user}")

        # 2. Change Directory (if specified)
        if remote_dir:
            try:
                ftp.cwd(remote_dir)
                print(f"Changed directory to: {remote_dir}")
            except ftplib.error_perm as e:
                print(f"Error changing directory: {e}")
                return

        # 3. List Files
        print("\n--- Directory Listing ---")
        ftp.retrlines('LIST')
        print("-------------------------\n")

        # 4. Download File (if specified)
        if file_to_download:
            print(f"Attempting to download '{file_to_download}'...")

            # Check if file exists in current listing (simple check)
            files = ftp.nlst()
            if file_to_download in files:
                local_filename = os.path.basename(file_to_download)

                with open(local_filename, 'wb') as f:
                    # RETR is the FTP command to retrieve a file
                    # retrbinary is used for binary files (images, zips, etc.)
                    ftp.retrbinary('RETR ' + file_to_download, f.write)

                print(f"Success! Saved to {os.path.abspath(local_filename)}")
            else:
                print(f"Error: File '{file_to_download}' not found in current directory.")

    except ftplib.all_errors as e:
        print(f"FTP Error: {e}")
    finally:
        if ftp:
            try:
                ftp.quit()
                print("Connection closed.")
            except:
                pass

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Simple FTP Client")
    parser.add_argument("host", help="FTP Server Address")
    parser.add_argument("-u", "--user", default="anonymous", help="Username (default: anonymous)")
    parser.add_argument("-p", "--password", default="", help="Password (default: empty)")
    parser.add_argument("-d", "--dir", help="Remote directory to navigate to")
    parser.add_argument("-f", "--file", help="Specific file to download")

    args = parser.parse_args()

    ftp_client(args.host, args.user, args.password, args.dir, args.file)

Usage

# List files on a public FTP server
python ftp_tool.py ftp.debian.org -d /debian

# Download a specific file
python ftp_tool.py ftp.example.com -u myuser -p mypass -f report.pdf

programming/python/python