pyftpdlib

2.2.0 · active · verified Tue Apr 14

pyftpdlib is a very fast, scalable, and asynchronous Python FTP server library. It provides a high-level portable interface to easily write efficient FTP servers, being the most complete RFC-959 FTP server implementation available for Python. It supports FTPS (RFC-4217), IPv6 (RFC-2428), Unicode filenames (RFC-2640), and virtual users. The library is currently at version 2.2.0 and actively maintained.

Warnings

Install

Imports

Quickstart

This quickstart sets up a basic FTP server with a virtual user (configurable via environment variables FTP_USER, FTP_PASS, FTP_HOME) and an anonymous read-only user. It listens on port 2121, sets connection limits, and configures basic logging. Remember to set `FTP_HOME` to a directory you wish to share, and `FTP_USER`/`FTP_PASS` for authenticated access.

import os
import logging
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

def main():
    # Setup a dummy authorizer for managing virtual users
    authorizer = DummyAuthorizer()

    # Add a user with read/write permissions
    ftp_user = os.environ.get('FTP_USER', 'user')
    ftp_pass = os.environ.get('FTP_PASS', '12345')
    home_dir = os.environ.get('FTP_HOME', os.getcwd())
    authorizer.add_user(ftp_user, ftp_pass, home_dir, perm='elradfmwMT')

    # Add an anonymous user with read-only permissions
    authorizer.add_anonymous(home_dir)

    # Instantiate FTP handler class
    handler = FTPHandler
    handler.authorizer = authorizer

    # Define a customized banner
    handler.banner = "pyftpdlib based FTP server ready."

    # Specify a masquerade address and the range of ports for passive connections
    # Uncomment and configure if behind a NAT
    # handler.masquerade_address = '151.25.42.11'
    # handler.passive_ports = range(60000, 65535)

    # Instantiate FTP server class and listen on all interfaces, port 2121
    address = ('', 2121)
    server = FTPServer(address, handler)

    # Set limits for connections
    server.max_cons = 256
    server.max_cons_per_ip = 5

    # Configure logging
    logging.basicConfig(level=logging.INFO, format='%(levelname)s:%(name)s:%(message)s')

    # Start ftp server
    print(f"Starting FTP server on {address[0] or '0.0.0.0'}:{address[1]} with user '{ftp_user}' and home '{home_dir}'")
    server.serve_forever()

if __name__ == "__main__":
    main()

view raw JSON →