Opened 12 months ago

Last modified 12 months ago

#123 new defect

Making using an alternative Port easier

Reported by: ftputiluser Owned by: schwa
Priority: minor Milestone:
Component: Library Version: 3.4
Keywords: Cc:


Thank you for documenting how to use a different 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

Change History (2)

comment:1 Changed 12 months ago by schwa

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 a session_factory argument is passed into the constructor.

An alternative could be to use the given FTPHost session_factory argument as the base_class argument for the session_factory function. However, the session_factory in FTPHost's constructor doesn't have to be a class, so in this case the inheritance in the session_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 the FTPHost constructor and require to pass in a session factory, which might be created with the session_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 the session_factory function) without having multiple ways to do the same thing (using the session_factory function vs. passing additional arguments like port into the FTPHost 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 the session_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)

comment:2 Changed 12 months ago by schwa

Priority: majorminor
Version: 3.4

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.

Last edited 12 months ago by schwa (previous) (diff)
Note: See TracTickets for help on using tickets.