So far, when someone asked whether ftputil supports SFTP, I've always replied that SFTP (not to be confused with FTPS!) is a different protocol than FTP and is therefore out of scope for ftputil.
After getting another question about SFTP and thinking about it, it occurred to me that I may be able to support SFTP if there is or I can create a session class that wraps an existing SFTP library. This session class could then be used for the FTPHost
session_factory
argument.
My search for Python SFTP libraries on PyPI was somewhat disappointing. Either packages are specialized for a very particular purpose or they have only very basic functionality or they don't seem to be maintained anymore.
That said, when looking at the dependencies of one package, I was reminded of Paramiko, which has been around in the Python ecosystem for a long time.
Although Paramiko doesn't seem to have an ftplib.FTP
-style class, there are two classes that may be useful:
ftputil.FTPHost
Now, the SFTP
class looks like I could wrap an instance of it in a class like SFTPHost
(maybe inheriting from FTPHost
) and not even have to write an ftplib.FTP
-like adapter. However, there are a few features in ftputil that may cause problems for this approach. Especially, I don't know yet if the SFTP
client has a stat cache feature similar to the one in ftputil. I suspect that using Paramiko's SFTP
class more or less directly may open a can of worms that would force me to reimplement some of the ftputil functionality for SFTP support. Possibly, the ftputil code could be refactored to interface both FTP and SFTP more easily, but I don't want to rely on that since the ftputil code is already complicated enough.
Therefore, I'm currently leaning toward implementing a session factory class that wraps Paramiko. Such a session class would have a much smaller API surface and the approach would readily benefit from ftputil's stat cache and automatic parser switching.
Then again, putting ftputil functionality on top of a custom session factory could mean that the (probably) more robust SFTP client is replaced with the workarounds in ftputil that are needed because of the shortcomings of FTP.
I think I should investigate both approaches (creating a session factory vs. wrapping the higher-level SFTP
class). Maybe a combination of both approaches would work best. For example, I could use a session class most of the time but also create an SFTPHost
class and implement specific methods in which I can just call the SFTP
methods.
Apart from the implementation, I need to look into specifying optional dependencies. I don't want to require Paramiko because it wouldn't be needed by users who only need FTP and FTPS support. On the other hand, if I can't specify Paramiko as a dependency at all, users wouldn't get any support for installing a Paramiko version that presumably is compatible with ftputil.
In any case, I expect that SFTP support, even if implemented, will initially be an experimental feature and may even be removed again if it doesn't seem practical in the end.
Hi ~dolfinus :-)
Well, there is https://docs.paramiko.org/en/stable/api/sftp.html
Yes, I mentioned/discussed it in the ticket description. :-)
I think the topic is rather complicated, so at least at the moment it doesn't seem worth it to work on Paramiko integration in ftputil.
Of course, and maybe that's what you meant, if someone needs "just" SFTP support without compatibility with the ftputil API, they may be fine with using Paramiko's
SFTP
class directly.