I've written a function to copy files remote-to-remote using SCP command, paramiko, pexpect, and paramiko-sftp. I want to make my code efficient; I'm new to Python and I don't know how. Here's my logic in 3 steps: 1. Find checksum of a file by executing `cksum` command in remote-1. 2. Executing SCP command from my local to copy file remote-1 to remote-2. 3. Again do checksum and compare both to give status. <!--- ---> class remote_file_operations(): """ Class which supports remote file operations """ def __init__(self, host=None, username=None, password=None, port=22): """ *Method description :* Initialize and setup connection :param host: Remote Host :type host: str :param username: Remote Host Username :type username: str :param password: Remote Host password :type password: str :param port: port to connect, default port is 22 :type port: int """ if host and username and password: self.sftp = None self.sftp_open = False self.client = paramiko.client.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: self.client.connect(host, port=port, username=username, password=password, timeout=10) except paramiko.ssh_exception.AuthenticationException: sys.exit("[Authentication Error] Please check user: '%s' or password" % username) except TimeoutError: sys.exit("Connection Refused") except socket.gaierror: sys.exit("Host Name: '%s' not found" % host) def _open_sftp_connection(self): """ *Method description :* Opens an SFTP connection if not already open """ if not self.sftp_open: self.sftp = self.client.open_sftp() self.sftp_open = True return self.sftp_open @staticmethod def file_check_sum(user, host, password, file_paths): """ *Method description :* Give check sum value by cksum command in remote. :param user: username :type user: str :param host: hostname :type host: str :param password: password :type password: str :param file_paths: list of file paths :type file_paths: list :return check_sum: dict with key as filename and value as checksum :type check_sum: dict """ status = True logger.console("Finding checksum ...") check_sum = dict() rmt_ses = remote_file_operations(host, user, password) for file_path in file_paths: _, stdout, stderr = rmt_ses.client.exec_command("ls %s" % file_path.replace("\\", "")) if b"No such file or directory" not in stderr.read(): for abs_file_path in stdout: cmd = "cksum %s" % abs_file_path.replace("\n", "").replace("\r", "") (_, stdout, stderr) = rmt_ses.client.exec_command(cmd) sum_line = stdout.read().decode("utf-8").replace(abs_file_path, "") file_name = abs_file_path.split("/")[-1] check_sum[file_name] = sum_line.replace("\n", "").strip() logger.console(check_sum) else: logger.error("File doesn't exist: %s:%s" % (host, file_path)) status = False rmt_ses.client.close() return status, check_sum @staticmethod def scp_remote_remote(host_1, user_1, password_1, host_2, user_2, password_2, src, dest): #pylint: disable=too-many-arguments,try-except-raise,too-many-locals,too-many-branches """ *Method description :* SCP files from one remote to another remote :param host_1: Remote host-1 :type host_1: str :param user_1: Remote user-1 :type user_1: str :param password_1: Remote Host-1 password :type password_1: str :param host_2: Remote host-2 :type host_2: str :param user_2: Remote user-2 :type user_2: str :param password_2: Remote Host-2 password :type password_2: str :param src: Source dir/file :type src: str :param dest: Destination dir/file :type dest: str :return output: Output generated while scp :type output: list """ exp_pwd_2, status, output = None, False, list() check, src_check_sum = remote_file_operations.file_check_sum(user_1, host_1, password_1, [src]) if check: command = "scp -r %s@%s:%s %s@%s:%s" % (user_1, host_1, src, user_2, host_2, dest) logger.console("Executing: %s" % command) try: child = pexpect.spawn(command, timeout=COPY_TIMEOUT) logger.console("Please wait while copying files from %s to %s ..." % (host_1, host_2)) exp_pwd_1 = child.expect(["password:", "want to continue connecting"], timeout=10) if exp_pwd_1 == 0: child.sendline(password_1) elif exp_pwd_1 == 1: child.sendline("yes") child.sendline(password_1) exp_pwd_2 = child.expect(["password:", "want to continue connecting"], timeout=10) if exp_pwd_2 == 0: child.sendline(password_2) elif exp_pwd_2 == 1: child.sendline("yes") child.sendline(password_2) child.expect(pexpect.EOF) for line in child.before.decode("utf-8").split("\r\n"): for sub_line in line.replace("\r", " ").split("ETA"): logger.console(sub_line) logger.console("\n") output.append(line.replace("\r", " ")) msg = "scp: %s: " % dest if msg + "Permission denied" in output or msg + "No such file or directory" in output: logger.error("Please check the dest path: '%s' exists or have access" % dest) elif "scp: /ome/virtuora: No such file or directory" % dest in output: logger.error("Please check the dest path: '%s' exists or have access" % dest) else: status = True except pexpect.exceptions.TIMEOUT: if "Permission denied" in child.before.decode("utf-8") or "password:"\ in child.before.decode("utf-8"): logger.error("Please check the username or password") except pexpect.exceptions.EOF: if "ld not resolve hostname" in child.before.decode("utf-8"): logger.error("Please check the Hostnames: '%s', '%s'" % (host_1, host_2)) if status: logger.console(src_check_sum) dst_file = [dest + "/" + src.split("/")[-1]] status, dst_check_sum = remote_file_operations.file_check_sum(user_2, host_2, password_2, dst_file) if status: for src_file, src_check in src_check_sum.items(): for dst_file, dst_check in dst_check_sum.items(): if src_file == dst_file and src_check == dst_check: logger.console("%s Transfered Successfully" % (src_file)) status = True else: logger.console("Something went wrong in file transferring") return status, output