sync_pull(sftp, remote_path, local_directory, recursive=True, ignore=None, keep_tree=False)
Like rsync but with SFTP, to download files.
WARNING: at the moment, sync is only done based on names. An improvement is to take other parameters into acccount like hash or size.
| Parameters: |
|
|---|
Source code in sftputil/sync.py
def sync_pull(
sftp,
remote_path,
local_directory,
recursive=True,
ignore=None,
keep_tree=False,
):
"""Like rsync but with SFTP, to download files.
WARNING: at the moment, sync is only done based on names. An improvement is to
take other parameters into acccount like hash or size.
Args:
sftp: (sftputil.SFTP) the SFTP connection to use for sync.
remote_path: (str|pathlib.Path) The remote path to sync. Can be a directory
or a file.
local_directory: (str|pathlib.Path) The local path where to sync the
remote_path. Must be an existing directory.
recursive: (bool) Whether to sync subdirectories as well.
ignore: (regex str) a pattern to ignore some paths (matches the full path).
keep_tree: (bool) If True, the whole directory path given in `remote_path`
is created in `local_directory`. If False, only the leaf is
synchronized. Default is False.
Example:
if `remote_path` is `/dir1/dir2/dir3/file`
When keep_tree=True, the file is written on this local path:
`<local_directory>/dir1/dir2/dir3/file`
When keep_tree=False, the file is written on this local path:
`<local_directory>/file`
Raises:
NotADirectoryError if `local_directory` is not a local directory.
FileNotFoundError if the `remote_path` points to nothing.
"""
remote_path = pathlib.PurePosixPath(remote_path)
# Check the remote_path existence
if not sftp.exists(remote_path):
raise FileNotFoundError(f"'{remote_path}' not found on '{sftp.hostname}'")
# Create the local directory if it does not exist
local_base_dir = pathlib.Path(local_directory)
if not local_base_dir.is_dir():
raise NotADirectoryError(local_base_dir)
# If remote_path is a file, just get it without walking
if sftp.is_file(remote_path):
_sync_pull_files(
sftp,
[remote_path.name],
remote_path.parent,
local_base_dir,
remote_path,
keep_tree,
ignore,
)
return
for walked_path, dirs, files in sftp.walk(remote_path):
# Start by syncing files
_sync_pull_files(
sftp, files, walked_path, local_base_dir, remote_path, keep_tree, ignore
)
# If sync is not recursive, just stop there
if not recursive:
break
# Create directories if necessary
for dirname in dirs:
local_dir_path = _build_local_path(
local_base_dir, remote_path, walked_path, dirname, keep_tree
)
local_dir_path.mkdir(parents=True, exist_ok=True)