Last active
January 29, 2025 09:15
-
-
Save mariusavram91/d84ce89645f5215a9c0b to your computer and use it in GitHub Desktop.
Copy remote files to local with Python's Paramiko
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
wrong print command
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
How to download multiple files with like option(*) ?
abc.I*.today's date.input