Back to Blog
Python

Python Paramiko SFTP Upload and Download Files

python paramiko sftp upload and download files: Learn to upload and download files over SFTP with Python Paramiko, including connection setup, error handling, and secu...

ParamikoSFTPPythonFile TransferSSH
Illustration of a Python script transferring files over SFTP using Paramiko, showing a secure connection between a client and server.

When you need to move files between machines over SSH, Paramiko's SFTP client is a common choice in Python. The core operations for python paramiko sftp upload and download files are straightforward: connect, open an SFTP session, then call put() or get(). This article walks through the essential steps, error handling, and security considerations.

Setting Up Paramiko

Install Paramiko with pip:

pip install paramiko

Import it in your script:

import paramiko

Paramiko is a pure Python implementation of SSHv2, so it works on most platforms without native dependencies.

Establishing an SFTP Connection

To start an SFTP session, you first create an SSH client and connect to the remote host. The connect method takes hostname, port, username, and password or key-based authentication.

ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('example.com', port=22, username='user', password='secret') sftp = ssh.open_sftp()

The set_missing_host_key_policy line is important. By default, Paramiko rejects unknown host keys. AutoAddPolicy automatically adds the host key to the local trust store on first connection. This is convenient for scripts but weakens security. See the security section below.

Once connected, open_sftp() returns an SFTPClient object that provides the file transfer methods.

Uploading a File with put()

The put() method uploads a local file to the remote path. Its signature is put(localpath, remotepath, callback=None). The callback, if provided, is called with the bytes transferred and the total size.

sftp.put('local_file.txt', '/remote/path/file.txt')

To track progress, pass a callback:

def progress(transferred, total): print(f'Transferred {transferred}/{total} bytes') sftp.put('local_file.txt', '/remote/path/file.txt', callback=progress)

The method returns an SFTPAttributes object with metadata about the remote file.

Downloading a File with get()

The get() method downloads a remote file to a local path. It has the same callback parameter.

sftp.get('/remote/path/file.txt', 'local_file.txt')

You can also read and write in chunks manually if you need more control, but for most cases get() is sufficient.

Handling Errors and Exceptions

Network issues, permission problems, and missing files raise exceptions. Common ones include FileNotFoundError for missing local or remote paths, PermissionError for access problems, and socket.error for connection failures. Wrap your transfer calls in try/except blocks to log and handle them gracefully.

try: sftp.put('local.txt', '/remote/upload.txt') except FileNotFoundError: print('Local or remote path does not exist') except PermissionError: print('Permission denied on remote server') except Exception as e: print(f'Unexpected error: {e}')

Always close the SFTP session and SSH client in a finally block or use context managers.

Security: Host Key Verification

AutoAddPolicy is convenient but vulnerable to man-in-the-middle attacks. In production, use RejectPolicy (the default) and explicitly set the expected host key. You can load the server's public key from a known_host file or embed it in your code.

ssh = paramiko.SSHClient() ssh.load_system_host_keys() # loads from ~/.ssh/known_hosts ssh.connect('example.com', username='user', password='secret')

If the host key does not match, Paramiko raises SSHException. This is the secure approach.

Performance: Reusing Connections and Buffering

Creating a new SSH connection for each file transfer adds significant overhead. If you need to move many files, reuse the same SFTPClient instance. Also, Paramiko uses a default buffer size for read/write operations. You can adjust it with the maxsize parameter in get() and put() for large files, but the default is usually adequate.

sftp.get(remote_path, local_path, maxsize=32768)

Larger buffers reduce the number of system calls but increase memory usage. Test with your file sizes to find a balance.

Using Context Managers for Cleaner Code

Paramiko's SSHClient and SFTPClient support context managers. This ensures resources are closed even if an exception occurs.

import paramiko with paramiko.SSHClient() as ssh: ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('example.com', username='user', password='secret') with ssh.open_sftp() as sftp: sftp.put('local.txt', '/remote/upload.txt') sftp.get('/remote/download.txt', 'local.txt')

The with block automatically closes the SFTP session and the SSH connection. This is the recommended pattern for scripts and automation tasks.

python paramiko sftp upload and download files: Practical Us | RYUSLOG DEV