The sftp: scheme
With uripath installed (pip install
"sftppath[uri]"), a URI whose scheme is sftp is an SFTPURIPath:
from uripath import URIPath
path = URIPath("sftp://deploy@files.example.org:2222/srv/data/report.txt")
print(type(path).__name__) # SFTPURIPath
print(path.read_text())
uripath finds the class through the entry point sftp of the group
uripath.schemes that this distribution declares, so nothing has to be
imported. Without the distribution, a path of the scheme still builds, joins and
prints, and its first request raises an ImportError that names
pip install "sftppath[paramiko]". Importing sftppath.uri without uripath
raises an ImportError that names pip install "sftppath[uri]"; import
sftppath never imports uripath.
One class of path behind a URI
An SFTPURIPath holds an SFTPPath for the server and path the URI
names and hands every request to it, so the errors, the connection caches and
the native recursive copy() and rm() are the same. The URI layer keeps
what is about URIs: parsing and joining, str() without the password, pickling
and the way paths of one endpoint share a backend. An error that names the
remote path names the URI.
Backends and ssh_config
Without backend=, a path builds an SFTPURIBackend; it makes the backend of the
class SFTPPATH_BACKEND selects for each server and account the paths name,
with the user, password and port of the URI. To set options, build one and pass
it:
from sftppath import SFTPBackend
from sftppath.uri import SFTPURIBackend
from uripath import URIPath
backend = SFTPURIBackend(SFTPBackend, timeout=10, known_hosts="/etc/ssh/ssh_known_hosts")
with backend:
root = URIPath("sftp://deploy@files.example.org/srv/data", backend=backend)
print([child.name for child in root.iterdir()])
A BaseSFTPBackend passed as backend= is used as it is for every path,
whatever host the URI names. ssh_config= (a path, an iterable of paths, None
or the default ~/.ssh/config) is a keyword of the constructor; it follows the
paths derived from the path on the same endpoint and not those on another host.
Moving between hosts
rename(), replace() and hardlink_to() from one server to another are
NotImplementedError, so move() copies and then deletes. A directory copied
to another server, or to a local path, takes the generic copy; a directory
copied within one server and one set of connections takes the native walk of the
asyncssh backend.