On Fri, Aug 21, 2009 at 5:53 PM, Zachary Voase<[email protected]> wrote: > > Hi Andi, > > On 21 Aug 2009, at 05:34, Andi Albrecht wrote: > >> Hi, >> >> I'm interested in working on #10355 "Add support for email backends." >> >> IMHO it's an good idea to make the email backend configurable. There >> are at least two use cases I can think of. The first is to send email >> with other services than SMTP, like App Engine as noted in the >> ticket's description. The second is to deliver email asynchronously, >> like the django-mailer application does already. > > I wholeheartedly agree. > >> The ticket currently needs a design decision, so my question is what >> the actual concerns to change this are. >> >> I would propose the following changes. It's a very simplistic approach >> that tries to keep the current API as much as possible: >> >> Add a new setting EMAIL_BACKEND. A string that can be resolved to a >> class. Default should be the current SMTP implementation. >> >> Provide a base class for mail backends. A mail backend must provide >> the method send_messages(email_messages) and must return the number of >> messages sent to provide backward compatibility. The constructor of a >> mail backend should take at least the keyword argument fail_silently >> (default: False). What I'm a bit unsure about are additional >> constructor arguments. Currently the SMTP backend allows in addition >> host, port, username, password and use_tls. Those are very >> SMTP-specific, but only username and password are used by the >> mail.send_mail* APIs. It would be an agreement to allow username and >> password in addition to fail_silently to not break the send_mail* API. >> The SMTP backend could accept host, port and use_tls as extra keywords >> again to provide backward compatibility for code that directly uses >> SMTPConnection (within Django SMTPConnection is not used outside >> django.core.mail). I would suggest to rename SMTPConnection to >> SMTPBackend, but only if this would break too much third-party code as >> SMTPConnection is mentioned in the docs. > > This I disagree with slightly. My main concern is the single-backend > architecture; many websites will probably want to use more than one > method for sending e-mail.
I'm not sure I agree with your assertion of "many"."Some" might be accurate. "Your" is probably more accurate :-) I've got many websites in the field, and not one of them has needed anything more than trivial email handling. We've managed to get to v1.1 and AppEngine support is the first time that pluggable email backends have really been raised as an issue. This is hardly surprising. After all, email is email. You have an SMTP server, you connect to it, you send your mail. AppEngine is a weird case in that they provide an email-sending API rather than using SMTP, but that's an artefact of the platform. Once you have one email sending capability, I find it hard to believe that most people will need a second. I don't doubt that there are applications that will require more than one mail server, but I'm comfortable calling them edge cases. If you have highly specialized mail requirements, then it makes sense that you should have a highly specialized mail server handling. That said, there isn't really that much difference between the simple and complex case - it's just a matter of defaults. Django needs to have a default Email backend, guaranteed available. EmailMessage.send() uses the 'default' backend - essentially just calling backend.send_messages([msg]) backend.send_messages() also exists as a direct call. SMTPConnection().send_messages() is really just a shortcut for instantiating and using an SMTP connection with the default settings. You're not compelled to use the default connection though. You could instantiate multiple instances of different backends, and use them to call other_backend.send_messages(). I see this working almost exactly as the Cache backend works right now. There is a base interface for caching. There are several cache backends; dummy and locmem are handy for testing, but if you're serious, the only one that gets used is memcached. There is a default cache instantiated as a result of the CACHE_BACKEND setting. For most people, this is all you will ever need. However, if you want to instantiate (and use) multiple caches (e.g., if you want to get really fancy about cache overflow and expiry policies), you can. > In addition, if mail backends only need to > implement one method, why not just have EMAIL_BACKEND refer to a > callable instead? Persistence of settings. s1 = Backend(host, port, username password) can be configured once, then s1 can be reused whenever needed. > I think a slightly better architecture would be this: > > * Make full use of the existing Django signals framework to send e- > mail. Have callables which implement 'send_messages()' connect to a > 'sendmail' signal through the use of a simple decorator or connector. What exactly is the use case where you need to have the 1-n cardinality provided by signals? The only use I can think of would be to have message delivery determined by the message itself - i.e., a message could be sent by SMTP server 1, SMTP server 2, or the AppEngine Server, depending on the recipient/content. If this is the use case, I put it to you that this is an _extreme_ edge case - and one that could be handled using a custom mail backend that does content-based dispatch - i.e., a mail backend that wraps other mail backend instances. Yours, Russ Magee %-) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/django-developers?hl=en -~----------~----~----~----~------~----~------~--~---
