{"id":6049,"library":"pyftpdlib","title":"pyftpdlib","description":"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.","status":"active","version":"2.2.0","language":"en","source_language":"en","source_url":"https://github.com/giampaolo/pyftpdlib/","tags":["ftp","server","async","network","file transfer"],"install":[{"cmd":"pip install pyftpdlib","lang":"bash","label":"Install pyftpdlib"}],"dependencies":[{"reason":"Optional, for FTPS (FTP over TLS/SSL) support.","package":"PyOpenSSL","optional":true},{"reason":"Optional, for tracking FTP server memory usage.","package":"psutil","optional":true}],"imports":[{"symbol":"DummyAuthorizer","correct":"from pyftpdlib.authorizers import DummyAuthorizer"},{"symbol":"FTPHandler","correct":"from pyftpdlib.handlers import FTPHandler"},{"symbol":"FTPServer","correct":"from pyftpdlib.servers import FTPServer"},{"note":"Used for FTPS (FTP over TLS/SSL) servers, requires PyOpenSSL.","symbol":"TLS_FTPHandler","correct":"from pyftpdlib.handlers import TLS_FTPHandler"},{"note":"For a multi-threaded concurrency model, if the default async model is not suitable.","symbol":"ThreadedFTPServer","correct":"from pyftpdlib.servers import ThreadedFTPServer"}],"quickstart":{"code":"import os\nimport logging\nfrom pyftpdlib.authorizers import DummyAuthorizer\nfrom pyftpdlib.handlers import FTPHandler\nfrom pyftpdlib.servers import FTPServer\n\ndef main():\n    # Setup a dummy authorizer for managing virtual users\n    authorizer = DummyAuthorizer()\n\n    # Add a user with read/write permissions\n    ftp_user = os.environ.get('FTP_USER', 'user')\n    ftp_pass = os.environ.get('FTP_PASS', '12345')\n    home_dir = os.environ.get('FTP_HOME', os.getcwd())\n    authorizer.add_user(ftp_user, ftp_pass, home_dir, perm='elradfmwMT')\n\n    # Add an anonymous user with read-only permissions\n    authorizer.add_anonymous(home_dir)\n\n    # Instantiate FTP handler class\n    handler = FTPHandler\n    handler.authorizer = authorizer\n\n    # Define a customized banner\n    handler.banner = \"pyftpdlib based FTP server ready.\"\n\n    # Specify a masquerade address and the range of ports for passive connections\n    # Uncomment and configure if behind a NAT\n    # handler.masquerade_address = '151.25.42.11'\n    # handler.passive_ports = range(60000, 65535)\n\n    # Instantiate FTP server class and listen on all interfaces, port 2121\n    address = ('', 2121)\n    server = FTPServer(address, handler)\n\n    # Set limits for connections\n    server.max_cons = 256\n    server.max_cons_per_ip = 5\n\n    # Configure logging\n    logging.basicConfig(level=logging.INFO, format='%(levelname)s:%(name)s:%(message)s')\n\n    # Start ftp server\n    print(f\"Starting FTP server on {address[0] or '0.0.0.0'}:{address[1]} with user '{ftp_user}' and home '{home_dir}'\")\n    server.serve_forever()\n\nif __name__ == \"__main__\":\n    main()","lang":"python","description":"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."},"warnings":[{"fix":"Upgrade to Python 3.6+ or downgrade pyftpdlib to version 1.5.10: `pip install pyftpdlib==1.5.10`.","message":"Python 2.7 support has been removed in pyftpdlib 2.0.0. Users requiring Python 2.7 compatibility must install version 1.5.10.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Delegate blocking tasks to separate threads or processes using Python's `threading` or `multiprocessing` modules, or ensure all I/O operations are non-blocking.","message":"As an asynchronous library, pyftpdlib will block the entire server if any long-running, blocking operations (e.g., `time.sleep()`, heavy database queries, slow disk I/O) are executed in the main event loop.","severity":"gotcha","affected_versions":"All"},{"fix":"Set `handler.masquerade_address` to the server's public IP and `handler.passive_ports` to a range of TCP ports for data transfers. Ensure these ports are forwarded by your NAT device.","message":"When the FTP server is behind a Network Address Translator (NAT), clients may fail to establish passive data connections unless `FTPHandler.masquerade_address` and `handler.passive_ports` are explicitly configured.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure clients support TLSv1.0 or newer. If legacy compatibility is critical, review `PyOpenSSL` configuration or consider older `pyftpdlib` versions (not recommended for security).","message":"Starting with version 2.0.0, the default SSL/TLS method for `TLS_FTPHandler` was changed from `SSLv23_METHOD` to `TLS_SERVER_METHOD`, disabling older and insecure SSLv2/SSLv3 protocols. This may break compatibility with very old FTP clients.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Manually set the `multiprocessing` start method to 'fork' (e.g., `multiprocessing.set_start_method('fork', force=True)`) if using `MultiprocessFTPServer` on affected platforms.","message":"On Python 3.14+, `MultiprocessFTPServer` may be broken on POSIX systems (excluding macOS) due to a change in the default `multiprocessing` method from 'fork' to 'forkserver'.","severity":"gotcha","affected_versions":"Python >=3.14, pyftpdlib >=2.0.0"}],"env_vars":null,"last_verified":"2026-04-14T00:00:00.000Z","next_check":"2026-07-13T00:00:00.000Z"}