Thank you for documenting how to use a different port: https://ftputil.sschwarzer.net/trac/wiki/Documentation#how-do-i-connect-to-a-non-default-port
In my use case I always need a different port.
It would be nice if FTPHost() would accept the port directly via kwarg.
Greetings from Chemnitz, Thomas Güttler
Hi Thomas,
Thanks again for your feedback! :-)
It should be possible to accept some (the most common) keyword arguments in the
FTPHost
constructor. The constructor could inspect these arguments and use the approach in section Session factories to create a session factory in the constructor. I suppose I would raise an exception if one of the special keyword arguments (e. g.port
) is used and asession_factory
argument is passed into the constructor.An alternative could be to use the given
FTPHost
session_factory
argument as thebase_class
argument for thesession_factory
function. However, thesession_factory
inFTPHost
's constructor doesn't have to be a class, so in this case the inheritance in thesession_factory
function wouldn't work. Therefore, I think this alternative is somewhat messy and I'd like to avoid it.Of course, another alternative would be to keep everything as it currently is, i. e. don't accept a
port
argument in theFTPHost
constructor and require to pass in a session factory, which might be created with thesession_factory
helper function. The advantage of the current approach is that it allows a lot of flexibility (the session factory doesn't have to be created with thesession_factory
function) without having multiple ways to do the same thing (using thesession_factory
function vs. passing additional arguments likeport
into theFTPHost
constructor).At the moment, I tend to keep everything regarding this ticket as it is.
In your specific case, you can inherit from
FTPHost
and support the port there or write a small factory that internally uses thesession_factory
function:def my_ftp_host(host, user, password, *, port): # Use a different base class if you want TLS support. session_factory = ftputil.session.session_factory(port=port) return ftputil.FTPHost(host, user, password, session_factory=session_factory)
Depending on what you need the functionality for (e. g. for testing), you may also want to fix one or more of host, user or password.
If you want, you can even implement the initially described approach yourself:
class MyFTPHost(ftputil.FTPHost): def __init__(self, *args, **kwargs): port = kwargs.pop("port", 21) session_factory = ftputil.session.session_factory(port=port) super().__init__(*args, **kwargs, session_factory=session_factory)
Priority changed to "minor" since simple workarounds exist (see above).
Version changed to "3.4" since it's the latest version and has the described behavior.
I'm closing this ticket. I don't want to add more arguments to the
FTPHost
constructor if they're already supported by the session factory concept and particularly thesession_factory
function. Although having one more argumentport
wouldn't be too bad, it's not clear whyport
should get a special consideration but not, say,use_passive_mode
. I'd rather keep the design orthogonal here and leave the responsibility to configure the port etc. to thesession_factory
function or custom classes derived fromFTPHost
.