Skip to content

Instantly share code, notes, and snippets.

@mariusavram91
Last active January 29, 2025 09:15
Show Gist options
  • Save mariusavram91/d84ce89645f5215a9c0b to your computer and use it in GitHub Desktop.
Save mariusavram91/d84ce89645f5215a9c0b to your computer and use it in GitHub Desktop.
Copy remote files to local with Python's Paramiko
import os
import posixpath
import logging
import paramiko
from pathlib import Path
from typing import List
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def transfer_files_via_sftp(
host: str,
port: int,
username: str,
password: str,
files: List[str],
remote_path: str,
local_path: str
) -> None:
"""
Transfer files from a remote server to a local directory via SFTP.
This function connects to an SSH server using the provided credentials, opens an SFTP session,
and downloads the specified files from the remote directory to the local directory.
:param host: The hostname or IP address of the SSH server.
:param port: The port number to connect to (default is 22).
:param username: The username for authentication.
:param password: The password for authentication.
:param files: A list of filenames to transfer.
:param remote_path: The remote directory containing the files.
:param local_path: The local directory to store the downloaded files.
:return: None
"""
ssh = paramiko.SSHClient()
try:
# Security: Verify host keys against system known hosts
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.RejectPolicy())
logger.info("Connecting to %s:%d as %s", host, port, username)
ssh.connect(hostname=host, port=port, username=username, password=password)
sftp = ssh.open_sftp()
logger.info("SFTP session established")
local_dir = Path(local_path)
try:
local_dir.mkdir(parents=True, exist_ok=True)
except PermissionError as e:
logger.error("Permission denied creating local directory: %s", str(e))
return
for file in files:
file_remote = posixpath.join(remote_path, file) # Use POSIX paths for remote
file_local = local_dir / file
try:
logger.info("Transferring: %s >>> %s", file_remote, file_local)
sftp.get(file_remote, str(file_local))
logger.info("Successfully transferred: %s", file)
except FileNotFoundError:
logger.error("File not found on remote: %s", file_remote)
except PermissionError:
logger.error("Permission denied writing local file: %s", file_local)
except Exception as e:
logger.error("Failed to transfer %s: %s", file, str(e))
sftp.close()
logger.info("SFTP session closed")
except paramiko.AuthenticationException:
logger.error("Authentication failed, please check your credentials")
except paramiko.SSHException as e:
logger.error("SSH error: %s", str(e))
except Exception as e:
logger.error("Unexpected error: %s", str(e))
finally:
ssh.close()
logger.info("SSH connection closed")
if __name__ == "__main__":
# Configuration
HOST: str = 'localhost' # Replace with actual host
PORT: int = 22
USERNAME: str = 'user' # Replace with actual username
PASSWORD: str = 'password' # Replace with actual password
REMOTE_FILES_PATH: str = '/remote_path/files/' # Replace with actual remote path
LOCAL_PATH: str = '/tmp/' # Replace with actual local path
FILES: List[str] = ['file1', 'file2', 'file3', 'file4'] # Replace with actual file names
transfer_files_via_sftp(HOST, PORT, USERNAME, PASSWORD, FILES, REMOTE_FILES_PATH, LOCAL_PATH)
@sreekumar360
Copy link

wrong print command

@msaad2209
Copy link

Hey,
Thanks for this code, wanted to copy any file which start with some specific string, for example my sftp has serval projects files and all projects files are saved as project_number and some file name and extension, I want to loop all the files of same project number, can you please guide?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment