a method to copy a folder or file from AWS instance to local device

        :param remote_path: string with path to copy contents on remote host
        :param local_path: [optional] string with path to folder or file on local host
        :param overwrite: [optional] boolean to enable file overwrite on remote host
        :param synopsis: [optional] boolean to simplify progress messages to one line
        :return: string with response

def get(self, remote_path, local_path='', overwrite=False, synopsis=True):

        '''
            a method to copy a folder or file from AWS instance to local device

        :param remote_path: string with path to copy contents on remote host
        :param local_path: [optional] string with path to folder or file on local host
        :param overwrite: [optional] boolean to enable file overwrite on remote host
        :param synopsis: [optional] boolean to simplify progress messages to one line
        :return: string with response
        '''

        title = '%s.transfer' % self.__class__.__name__

    # validate inputs
        input_fields = {
            'local_path': local_path,
            'remote_path': remote_path
        }
        for key, value in input_fields.items():
            if value:
                object_title = '%s(%s=%s)' % (title, key, str(value))
                self.fields.validate(value, '.%s' % key, object_title)

    # verify remote path exists
        from os import path
        self.ec2.iam.printer_on = False
        try:
            test_path_cmd = 'ls %s' % remote_path.replace(' ','\ ')
            self.script(test_path_cmd)
        except:
            raise ValueError('%s does not exist on remote host. Canceling transfer.' % remote_path)
        self.ec2.iam.printer_on = True
        remote_path_root, remote_path_node = path.split(remote_path)
        if not remote_path_root:
            remote_path_root = '~/'
        remote_path = remote_path.replace(' ', '\ ')
        remote_path_root = remote_path_root.replace(' ','\ ')

    # verify local root exists
        if local_path:
            local_path_root, local_path_node = path.split(local_path)
            if not local_path_root:
                local_path_root = './'
                local_path = path.join(local_path_root, local_path_node)
            if not path.exists(local_path_root):
                raise ValueError('%s folder does not exist on localhost. Canceling transfer.' % local_path_root)
        else:
            from copy import deepcopy
            local_path_node = deepcopy(remote_path_node)
            local_path = path.join('./', local_path_node)
            local_path_root = './'
        remote_path_node = remote_path_node.replace(' ', '\ ')
    
    # verify local path does not exist
        if not overwrite:
            if path.exists(local_path):
                raise ValueError('%s already exists on localhost. Canceling transfer.' % local_path)

    # verify installation of scp on remote host
        self.ec2.iam.printer_on = False
        if not self.scp:
            try:
                self.script('scp')
                self.scp = True
            except Exception as err:
                if str(err).find('usage: scp') > 1:
                    self.scp = True
                else:
                    raise Exception('SCP needs to be installed on remote host. Canceling transfer.\nOn remote host, try: sudo yum install -y git')

    # determine sudo privileges
        sudo_insert = 'sudo '
        user_abs = self.script('readlink -f ~/')
        remote_abs = self.script('readlink -f %s' % remote_path_root)
        if remote_abs.find(user_abs) > -1:
            sudo_insert = ''
        self.ec2.iam.printer_on = True

    # initiate transfer process
        remote_host = '[%s@%s]' % (self.login_name, self.instance_ip)
        if synopsis:
            self.ec2.iam.printer('Transferring %s:%s to %s ... ' % (remote_host, remote_path, local_path), flush=True)
            self.ec2.iam.printer_on = False
        self.ec2.iam.printer('Initiating transfer of %s:%s to %s ... ' % (remote_host, remote_path, local_path))

    # construct temporary file folder on localhost
        from labpack import __module__
        from labpack.storage.appdata import appdataClient
        client_kwargs = {
            'collection_name': 'TempFiles',
            'prod_name': __module__
        }
        tempfiles_client = appdataClient(**client_kwargs)

    # make remote folder into a tar file
        from time import time
        tar_file = 'temp%s.tar.gz' % str(time())
        local_tar_path = path.join(tempfiles_client.collection_folder, tar_file)
        remote_tar_path = path.join('~/', tar_file)
        self.ec2.iam.printer('Creating temporary file %s:%s ... ' % (remote_host, remote_tar_path))
        create_command = '%star -czf %s -C %s %s' % (sudo_insert, remote_tar_path, remote_path_root, remote_path_node)
        self.script(create_command) 

    # define cleanup functions
        def _cleanup_local(tar_file, local_tar_path):
            self.ec2.iam.printer('Cleaning up temporary file %s ... ' % local_tar_path, flush=True)
            tempfiles_client.delete(tar_file)
            self.ec2.iam.printer('done.')
        def _cleanup_remote(remote_host, tar_path):
            self.ec2.iam.printer('Cleaning up temporary file %s:%s ... ' % (remote_host, tar_path))
            self.script('rm %s' % tar_path)
            
    # initiate scp transfer of tar file
        copy_msg = 'Copying %s:%s to %s ... ' % (remote_host, remote_tar_path, local_tar_path)
        error_msg = 'Failure copying file %s:%s to localhost.' % (remote_host, remote_tar_path)

    # use paramiko on windows systems
        if self.localhost.os.sysname in ('Windows'):
            ssh_key = paramiko.RSAKey.from_private_key_file(self.pem_file)
            client = paramiko.SSHClient()
            client.load_system_host_keys()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect(hostname=self.instance_ip, username=self.ec2.iam.user_name, pkey=ssh_key)
            scp_transport = scp.SCPClient(client.get_transport())
            self.ec2.iam.printer(copy_msg, flush=True)
            try:
                response = scp_transport.get(remote_tar_path, local_tar_path)
            except:
                self.ec2.iam.printer('ERROR.')
                _cleanup_remote(remote_host, remote_tar_path)
                raise Exception(error_msg)
            client.close()
            self.ec2.iam.printer('done.')

    # use scp on other systems
        else:
            self.ec2.iam.printer(copy_msg, flush=True)
            sys_command = 'scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentityFile="%s" %s@%s:%s "%s"' % (self.pem_file, self.login_name, self.instance_ip, remote_tar_path, local_tar_path)
            from subprocess import check_output, CalledProcessError, STDOUT
            try:
                response = check_output(sys_command, shell=True, stderr=STDOUT).decode('utf-8')
                self.ec2.iam.printer('done.')
            except CalledProcessError as err:
                self.ec2.iam.printer('ERROR.')
                _cleanup_remote(remote_host, remote_tar_path)
                print(err)
                raise Exception(error_msg)

    # extract tar file to local path and rename directory
        try:
            import tarfile
            with tarfile.open(local_tar_path, 'r:gz') as tar:
                tar.extractall(local_path_root)
                tar.close()
            if local_path_node.replace(' ','\ ') != remote_path_node:
                from shutil import move
                src = path.join(local_path_root, remote_path_node)
                dst = path.join(local_path_root, local_path_node)
                move(src, dst)
        except Exception as err:
            self.ec2.iam.printer('ERROR.')
            _cleanup_remote(remote_host, remote_tar_path)
            _cleanup_local(tar_file, local_tar_path)
            print(err)
            raise Exception(error_msg)
            
    # cleanup temporary files
        _cleanup_remote(remote_host, remote_tar_path)
        _cleanup_local(tar_file, local_tar_path)

    # return response
        self.ec2.iam.printer('Transfer of %s:%s to %s complete.' % (remote_host, remote_path, local_path))
        if synopsis:
            self.ec2.iam.printer_on = True
            self.ec2.iam.printer('done.')

        return response