[Twisted-Python] smtp.SMTP help

Anders Hammarquist iko at cd.chalmers.se
Wed Oct 1 19:47:17 EDT 2003

Hi Greg!

In a message of Wed, 01 Oct 2003 17:20:17 EDT, Greg writes:
>Working on an SMTP filter (consisting of an SMTP server that receives 
>messages, some code that mangles them, then and SMTP client that forwards 
>them along). The first step is to get a functioning SMTP server working, and 
>I'm having some trouble with SMTPFactory / SMTP. I've overloaded the validate 
>methods in an attempt accept emails to and from any domain, but I can't 
>figure out how to hook in a class that implements IMessageDelivery:

There are several problems with your code, but to my eye it looks like
confusion between several methods of using the SMTP class. Until recently,
the IMessageDelivery method didn't exists, and you needed to override
SMTP to implement validateTo and validateFrom. Now, you can instead pass
an IMessageDelivery to SMTP, either directly or using the authenticator
(and if you do, you shouldn't need to subclass SMTP - and if your twisted
is recent enough, you have to use the IMessageDelivery method).

You do need to make your own factory though, since the one that's there
doesn't deal with IMessageDelivery()s yet. Something like

class MySMTPFactory(SMTPFactory):
	def buildProtocol(self, addr):
		p = self.protocol(MyMessageDelivery())
		p.factory = self
		p.portal = self.portal
		p.host = self.domain
		return p

>class MySMTPProtocol(SMTP):
>	def validateTo(self, user):
>		d = defer.Deferred()
>		reactor.callLater(0, self.fakeSucceed())
>		return d

You don't need this code, but I still want to point out that it doesn't
do anything useful, and is overcomplicated. 

First, validateTo may return an IMessage or a deferred returning an
IMessage, so you don't need the deferred, you can just return you
IMessage directly. Secondly the deferred is never called, so it will
never return, and thus your SMTP server stops here.

reactor.callLater() just calls another function asynchrously and discards
the result. If you want to pass back a result from a callLater, you need
to pass along the deferred and call it in the function you callLater()ed.

>class MyIMessage:
>	__implements__ = (smtp.IMessageDelivery)

You seem to have mixed up IMessage and IMessageDelivery. You need both.
Your IMessageDelivery.validateTo() should return an IMessage (or a deferred
returning an IMessage).


 -- Of course I'm crazy, but that doesn't mean I'm wrong.
Anders Hammarquist                                  | iko at cd.chalmers.se
Physics student, Chalmers University of Technology, | Hem: +46 31 88 48 50
G|teborg, Sweden.           RADIO: SM6XMM and N2JGL | Mob: +46 707 27 86 87

More information about the Twisted-Python mailing list